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

问题描述 投票:6回答:2

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

现在我有以下问题:

  1. 如果我使用线程(Qt),那么我在哪里进行select系统调用来监控串口?
  2. select系统调用线程是否安全?
  3. 它是CPU密集型的,因为我的应用程序中发生了很多事情,包括GUI更新?

如果你觉得这些问题很荒谬,请不要介意。我从未使用过这种串行通信机制。

c++ unix serial-port
2个回答
7
投票

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

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

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

希望这可以帮助。

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

只要你不是在多个线程中对同一个描述符进行selecting就不应该有问题。


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.