6

我正在使用 2.6.24.3 内核为嵌入式 Linux 项目开发用户空间应用程序。我的应用程序通过创建 2 个 pthreads 在两个文件节点之间传递数据,每个 pthreads 都休眠直到异步 IO 操作完成,此时它唤醒并运行完成处理程序。

完成处理程序需要跟踪有多少传输未决,并维护一些链表,一个线程将添加到另一个线程将删除这些链表。

// sleep here until events arrive or time out expires
for(;;) {
    no_of_events = io_getevents(ctx, 1, num_events, events, &timeout);
    // Process each aio event that has completed or thrown an error
    for (i=0; i<no_of_events; i++) {
        // Get pointer to completion handler
        io_complete = (io_callback_t) events[i].data;
        // Get pointer to data object
        iocb = (struct iocb *) events[i].obj;
        // Call completion handler and pass it the data object
        io_complete(ctx, iocb, events[i].res, events[i].res2);
    }
}

我的问题是这个...

有没有一种简单的方法可以防止当前活动的线程在运行完成处理程序时让步,而不是沿着互斥锁/自旋锁路线走下去?

或者如果不能配置 Linux 以防止在持有互斥锁/自旋锁时产生 pthread?

4

3 回答 3

6

您可以使用sched_setscheduler()系统调用将线程的调度策略临时设置为SCHED_FIFO,然后再重新设置。从sched_setscheduler()手册页:

一个SCHED_FIFO进程一直运行,直到它被 I/O 请求阻塞,被更高优先级的进程抢占,或者它调用sched_yield(2).

(在这种情况下,“进程”实际上是指“线程”)。

然而,这是一个相当可疑的要求。您希望解决的问题是什么?如果您只是想保护完成处理程序的链接列表免受并发访问,那么普通的互斥锁就是要走的路。让完成线程锁定互斥体,删除列表项,解锁互斥体,然后调用完成处理程序。

于 2010-05-19T13:26:58.923 回答
1

我想你会想在这里使用互斥锁/锁来防止竞争条件。互斥锁绝不是巫术魔法,甚至可以使您的代码比使用任意系统特定功能更简单,您可能需要跨系统移植这些功能。不过,不知道后者是否对您来说是个问题。

于 2010-05-19T15:56:19.033 回答
1

我相信出于错误的原因,您在这里试图超越 Linux 调度程序。

正确的解决方案是使用互斥锁来防止完成处理程序并行运行。让调度程序完成它的工作。

于 2010-05-19T16:04:10.093 回答