c++ - 线程中的 Select() 系统调用?

标签 c++ unix serial-port

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

现在我有以下问题:

  1. 如果我使用的是线程 (Qt),那么应该将选择系统调用放在哪里以监视串行端口?
  2. select 系统调用线程安全吗?
  3. 它是否占用大量 CPU,因为我的应用程序中发生了很多事情,包括 GUI 更新?

如果您觉得这些问题很可笑,请不要介意。我从来没有使用过这样的串口通信机制。

最佳答案

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

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

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

希望这对您有所帮助。

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

只要您不是在多个线程中选择相同的描述符,就不会有问题。

关于c++ - 线程中的 Select() 系统调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1048218/

相关文章:

c++ - 树遍历如何工作?

c++ - 如何将数据文件加载到自动 Excel 工作表文档?

c++ - 为单选按钮创建组

unix - 为什么基础图像上有这么多层? docker

unix - 尝试使用 'sed -i' 修改文件时出错

node.js - 使用 NodeJs serialPort - 错误 : %1 is not a valid Win32 application

windows - USB 设备的 SetupComm、SetCommState、SetCommTimeouts 失败

c++ - glm的orientAngle()函数中的 "reference vector"是什么?

java - jssc getInputStream() getOutputstream()

c++ - 调试和自由执行中的信号处理