在辅助线程中调用 select()/pselect() 会导致主线程阻塞吗?

Posted

技术标签:

【中文标题】在辅助线程中调用 select()/pselect() 会导致主线程阻塞吗?【英文标题】:Will calling select()/pselect() in secondary thread cause primary thread to block? 【发布时间】:2011-05-29 02:38:51 【问题描述】:

我正在处理一个需要几个辅助线程的应用程序,每个辅助线程将负责多个文件句柄(至少 1 个,超过 10 个)。文件句柄不在线程之间共享,因此当selecting 查看准备好读/写的内容时,我不必担心一个辅助线程会阻塞另一个线程。我要确定的是,在执行select/pselect 调用时,两个辅助线程都不会导致主线程停止执行。

我想这不是问题 - 有人会想像这样的事情会在网络服务器中完成 - 但是当我找不到任何明确表示“是的,你可以做到这一点”的内容时谷歌搜索。我的假设是否正确,这不会导致任何问题?

为了澄清,我所拥有的看起来像:

执行的主线程(select() 循环处理传入的命令消息和传出的响应)

辅助线程#1(select()循环提供服务)

辅助线程 #2(select() 循环提供另一个服务)

正如我之前提到的,没有一个文件句柄在线程之间共享 - 它们是在单个线程中创建、使用和销毁的,而其他线程不知道它们的存在。

【问题讨论】:

【参考方案1】:

不,您不必担心它们会阻塞主线程。我在各种项目的多个线程中使用了 select。只要它们有不同的 FDSETS 就可以了,每个都可以像独立的事件循环一样使用。

【讨论】:

这是我的想法,但select 手册页提到它会在等待文件描述符准备好(或超时)时阻塞 进程 .这就是为什么我想知道这是字面意思(进程被阻塞),还是仅仅意味着当前的执行线程。 @Will 正如 SB 所说,只要确保文件描述符不同。 这里是select 的正确“手册页”:pubs.opengroup.org/onlinepubs/9699919799/functions/select.html 除了更改历史记录部分之外,您根本找不到其中提到的“进程”。在 Linux 等许多系统上,您可以安装 POSIX 手册页,该手册页将显示为 man 部分 3p,这非常有用,因为供应商手册页往往包含误导性信息。 @R:+1 谢谢。我讨厌有令人困惑/误导性的文档。【参考方案2】:

选择不应该阻止整个过程吗? 你试过在socket上设置非阻塞模式吗?

另外,请参阅 select_tut 手册页以获得一些帮助。

这是来自select_tut 手册页的相关部分:

So what is the point of select()? Can't I just read and write to my descriptors whenever I want? The point of select() is that it watches multiple descriptors at the same time and properly puts the process to sleep if there is no activity.

【讨论】:

套接字是非阻塞的。我在选择手册页中阅读了一些内容,它会阻止该过程,这就是我提出问题的原因。 谁把如此糟糕的教程打包成手册页?

以上是关于在辅助线程中调用 select()/pselect() 会导致主线程阻塞吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在套接字关闭时唤醒 select()?

select epoll总结

c#中如何跨线程调用windows控件

java并发之同步辅助类CyclicBarrier

在C ++中是否可以从主线程中执行辅助线程中运行的函数?

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