在线程中选择()系统调用?

时间:2009-06-26 09:31:33

标签: c++ unix serial-port

我正在从多个串口读取数据。目前我正在使用自定义信号处理程序(通过设置sa_handler)来比较和唤醒基于文件描述符信息的线程。我正在寻找一种方法,让单个线程具有独特的信号处理程序,在这方面我发现将使用select系统调用。

现在我有以下问题:

  1. 如果我使用线程(Qt),那么我在哪里进行select系统调用以监控串口?
  2. 选择系统调用线程是否安全?
  3. 是否为CPU密集型,因为我的应用程序中发生了很多事情,包括GUI更新?
  4. 请不要介意,如果你觉得这些问题很荒谬。我从未使用过这种串行通信机制。

2 个答案:

答案 0 :(得分:7)

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

如果我理解正确,你会根据某些描述符的状态唤醒线程。更好的方法是让每个线程都有自己的描述符并调用select本身。你看,select不会修改系统状态,只要你使用线程局部变量,它就是安全的。但是,您肯定希望确保不关闭线程所依赖的描述符。

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

希望这有帮助。

编辑:此外,select / poll在多个线程中使用相同的描述符时可能会产生不可预测的结果。原因很简单,第一个线程可能被唤醒,因为描述符已准备好读取,但第二个线程必须等待 next “可用于读取”唤醒。

只要你没有{{1}在多个线程中使用相同的描述符,就不应该有问题。

答案 1 :(得分:0)

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

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

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