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

发布于 2024-07-25 17:19:10 字数 345 浏览 1 评论 0原文

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

现在我有以下问题:

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

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

I am reading data from multiple serial ports. At present I am using a custom signal handler (by setting sa_handler) to compare and wake threads based on file descriptor information. I was searching for a way out to have individual threads with unique signal handlers, in this regard I found that select system call is to be used.

Now I have following questions:

  1. If I am using a thread (Qt) then where do I put the select system call to monitor the serial port?
  2. Is the select system call thread safe?
  3. Is it CPU intensive because there are many things happening in my app including GUI update?

Please do not mind, if you find these questions ridiculous. I have never used such a mechanism for serial communication.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扛刀软妹 2024-08-01 17:19:11

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

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

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

希望这可以帮助。

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

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

The POSIX specification (select) is the place to look for the select definition. I personally recommend poll - it has a better interface and can handle any number of descriptors, rather than a system-defined limit.

If I understand correctly you're waking threads based on the state of certain descriptors. A better way would be to have each thread have its own descriptor and call select itself. You see, select does not modify the system state, and as long as you use thread-local variables it'll be safe. However, you will definitely want to ensure you do not close a descriptor that a thread depends on.

Using select/poll with a timeout leaves the "waiting" up to the kernel side, which means the thread is usually put to sleep. While the thread is sleeping it is not using any CPU time. A while/for loop on a select call without a timeout on the other hand will give you a higher CPU usage as you're constantly spinning in the loop.

Hope this helps.

EDIT: Also, select/poll can have unpredictable results when working with the same descriptor in multiple threads. The simple reason for this is that the first thread might be woken up because the descriptor is ready for reading, but the second thread has to wait for the next "available for reading" wakeup.

As long as you're not selecting on the same descriptor in multiple threads you should not have a problem.

梦里泪两行 2024-08-01 17:19:11

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

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

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

It is a system call -- it should be thread safe, I think.

I did not do this before, but I would be rather surprised, if it where not. How CPU intensive select() is, depends in my opinion largely on the number of file handles you are waiting for. select() is mostly used, to wait for a number (>1) of file handles to become ready.

It should also be mentioned that select() should not be used to poll the file handles -- for performance reason. Normal usage is: You have your work done and some time can elapse till the next thing is going on. Now you suspend your process with select and let another process run. select() normally does suspend the active process. How this works together with threads, I am not sure! I would think, that the whole process (and all threads) are suspended. But this might be documented. It also could depend (on Linux) whether you use system-threads or User-Threads. The kernel will not know User-Threads and hence suspend the whole process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文