2009-06-26 48 views
5

我正在从多个串行端口读取数据。目前我正在使用自定义信号处理程序(通过设置sa_handler)根据文件描述符信息来比较和唤醒线程。我正在寻找一种解决方案,让单个线程拥有独特的信号处理程序,在这方面,我发现要使用选择系统调用。在线程中选择()系统调用?

现在我以下的问题:

  1. 如果我使用一个线程(QT),那么我应该把选择的系统调用监控的串行端口?
  2. 选择系统调用线程安全吗?
  3. 它是CPU密集型的,因为我的应用程序中发生了很多事情,包括GUI更新?

请不要介意,如果您发现这些问题很荒谬。我从来没有使用过这样的串行通信机制。

回答

7

POSIX specification (select)是寻找select定义的地方。我个人推荐poll - 它有一个更好的接口,可以处理任意数量的描述符,而不是系统定义的限制。

如果我理解正确,你是基于某些描述符的状态唤醒线程。更好的方法是让每个线程都有自己的描述符和呼叫选择自己。你看,选择不会修改系统状态,并且只要你使用线程局部变量,它将是安全的。但是,您一定要确保不要关闭线程所依赖的描述符。

使用select/poll超时会让“等待”直到内核端,这意味着线程通常会进入睡眠状态。当线程正在休眠时,它不使用任何CPU时间。另一方面,在没有超时的情况下,select呼叫上的while/for循环将使您的CPU使用率更高,因为您一直在循​​环中旋转。

希望这会有所帮助。

编辑:另外,在多线程相同描述工作时select/poll可以有不可预知的结果。原因很简单,第一个线程可能会被唤醒,因为描述符已准备好读取,但第二个线程必须等待下一个“可用于读取”唤醒。

只要你不是select在多个线程相同的描述符,你应该没有问题。

+0

Gud info!一个问题。线程如何知道它需要唤醒,如果套接字fd准备好进行读/写操作。内核是否给线程一些中断? – 2013-05-19 18:20:20

0

这是一个系统调用 - 它应该是线程安全的,我认为。

我以前没有这样做过,但我会感到很惊讶,如果它不在那里。 CPU密集度如何,在很大程度上取决于您正在等待的文件句柄的数量。主要使用select()来等待一个(> 1个)文件句柄准备就绪。

还应该提到的是,select()不应该用于轮询文件句柄 - 出于性能原因。正常的用法是:你的工作已经完成,并且有一段时间可以流逝直到下一件事发生。现在,您暂停您的选择并让其他进程运行。 select()通常会暂停活动进程。如何与线程一起工作,我不确定!我认为,整个过程(以及所有线程)都被暂停。但这可能是有记录的。它也可以取决于(在Linux上)是否使用系统线程或用户线程。内核不会知道用户线程并因此暂停整个过程。

+0

这真的不是一个好答案。很多猜测工作...什么是“用户线程”呢?! – 2018-03-03 02:28:41