我可以阻止Linux用户空间pthread在关键代码中产生吗?

Ker*_*itG 5 linux scheduling pthreads embedded-linux

我正在使用2.6.24.3内核为嵌入式Linux项目开发用户空间应用程序.我的应用程序通过创建2个pthread来在两个文件节点之间传递数据,每个pthread都会休眠,直到异步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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是......

是否有一种简单的方法可以阻止当前活动线程在运行完成处理程序时屈服而不是沿着互斥锁/自旋锁路由?

或者失败,可以配置Linux以防止在保持互斥锁/自旋锁时产生pthread?

caf*_*caf 5

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

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

(在这种情况下,“进程”实际上意味着“线程”)。

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

  • @KermitG:如果您担心完成处理程序代码本身与另一个线程中的代码竞争,那么简单地防止抢占将无济于事。当完成处理程序启动时,另一个线程可能已经在临界区中;即使在完成处理程序运行时暂停它,它仍然会看到它正在处理的数据从它下面改变出来。一般来说,如果处理程序中的代码可以竞争,则处理程序本身应该负责锁定。 (4认同)