我正在使用 Berkeley 套接字开发 Windows/Unix 多线程服务器应用程序网络层,并偶然发现了一个问题:
- 我有一个线程在 select 处等待给定的 fd 集。
- 从另一个线程,我需要向其中一个 fd 集添加一个套接字。
- 由于选择当前处于待处理状态,因此无法完成并导致饥饿。
可能的解决方案是为选择添加超时。我在使用 select 解决网络问题的网站上看到过这一点(可以追溯到 15 年前)。
问题是:
还有其他解决方案吗?等待超时仍然会导致某种程度的饥饿,并占用 select-waiter 线程的 CPU 时间。我认为可以重新设计应用程序,但添加套接字也是从选择等待线程不知道(而且绝对应该不知道)的线程中完成的,因此无法避免这种情况。
如果不是,应该选择什么样的超时才能实现最佳性能/服务质量?
另请注意,我确实意识到使用更高级的 API(iocp、kqueue 等)或可以为我完成此操作的库会更好,但这对我来说不是一个选择观点。
谢谢
最佳答案
创建一个额外的套接字对,并将其中一个套接字添加到每个 select
中。要中断正在运行的 select
,请通过另一个套接字向其发送消息。
仅在 Unix 端,可以使用 pthread_kill
向等待线程发送任何信号(例如 SIGUSR1
)。 select
然后返回负值,并且 errno
将设置为 EINTR
。但 Windows 端没有类似的东西。
关于c++ - C/C++ 当 select 挂起时将套接字添加到 fd_set,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23443601/