我正在从多个串口读取数据。目前我正在使用自定义信号处理程序(通过设置sa_handler)来比较和唤醒基于文件描述符信息的线程。我正在寻找一种方法,让单个线程具有独特的信号处理程序,在这方面我发现将使用select系统调用。
现在我有以下问题:
请不要介意,如果你觉得这些问题很荒谬。我从未使用过这种串行通信机制。
答案 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上)依赖于系统线程还是用户线程。内核不会知道用户线程,因此暂停整个过程。