2010-05-19 50 views
5

我正在使用2.6.24.3内核为嵌入式Linux项目开发用户空间应用程序。 我的应用程序通过创建2个pthread来在两个文件节点之间传递数据,每个睡眠直到异步IO操作完成,然后唤醒并运行完成处理程序。我可以防止在关键代码中产生Linux用户空间pthread吗?

完成处理程序需要跟踪有多少个传输处于挂起状态,并维护一个线程将添加到另一个线程并将另一个线程移除的链接列表。

// 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

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

SCHED_FIFO过程运行,直至 它是由I/O请求阻挡时,它是 更高优先级 过程抢占,或它调用sched_yield(2)

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

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

+0

该要求主要是试图保持代码简单,有几个项目需要在完成处理程序中互斥,但如果您可以确保它只会在处理程序之外产生,我认为您不需要任何。 我想另一种选择是在整个处理程序周围放一个粗糙的互斥体。 – KermitG 2010-05-19 15:10:33

+4

@KermitG:如果您担心完成处理程序代码本身与另一个线程中的代码竞争,那么只需防止抢占将无济于事。当完成处理程序启动时,另一个线程可能已经在临界区内;即使在完成处理程序运行时暂停它,它仍然会看到它正在处理的数据将从其下方更改。通常,如果处理程序中的代码可以竞争,则处理程序本身应负责锁定。 – caf 2010-05-19 21:47:49

1

我想你会想在这里使用互斥/锁来防止竞争条件。互斥体绝不是巫术魔法,甚至可以使您的代码更简单,而不是使用任意系统特有的功能,这些功能您可能需要跨系统进行端口连接。不过,不知道后者是否是你的问题。

1

我相信你在这里试图超越Linux调度器,原因是错误的。

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

相关问题