简体   繁体   English

C / C ++在选择未决时将套接字添加到fd_set

[英]C/C++ Add socket to fd_set when select is pending

I'm working on a windows/unix multithreaded server application network layer with Berkeley sockets and stumbled upon a problem: 我正在使用Berkeley套接字在Windows / unix多线程服务器应用程序网络层上工作,偶然发现了一个问题:

  • I have one thread waiting at select with given fd sets. 我有一个线程在等待给定fd集的选择。
  • From another thread, I need to add a socket to one of the fd sets. 从另一个线程,我需要向一个fd集添加一个套接字。
  • As the select is currently pending, it cannot be done and leads to a starvation. 由于选择当前处于待处理状态,因此无法完成选择并导致饥饿。

Possible solution is to add a timeout to the select. 可能的解决方案是将超时添加到选择中。 I have seen that on sites addressing networking with select (dated 15 years back). 我已经看到在某些网站上使用select(距今15年)进行网络连接。

The question is: 问题是:
Are there any other solutions? 还有其他解决方案吗? Waiting for timeout still leads to some level of starvation and takes CPU time from the select-waiter thread. 等待超时仍然会导致某种程度的饥饿,并从选择等待者线程中占用CPU时间。 I thought it would be possible to redesign the application but adding sockets is also done from threads that select-waiter thread has (and most definitely should have) no idea about, so the condition cannot be avoided. 我认为可以重新设计应用程序,但是添加套接字也可以从选择等待者线程不知道(并且绝对应该不知道)的线程中完成,因此无法避免这种情况。

If not, what sort of timeout should be chosen to achieve best performance / service quality? 如果没有,应该选择哪种超时来达到最佳性能/服务质量?

Also note that I do realize that it would be better idea to use more advanced API (iocp, kqueue, ...) or a lib that would do it for me, but that is not an option for me at the given point. 另请注意,我的确意识到使用更高级的API(iocp,kqueue,...)或可以为我完成任务的lib是一个更好的主意,但在给定的时间点上,这不是我的选择。

Thanks 谢谢

Create an additional socket pair and add one of these sockets to every select . 创建一个额外的套接字对,并将其中一个套接字添加到每个select To interrupt a running select , send a message to it via the other socket. 要中断正在运行的select ,请通过另一个套接字向其发送消息。

On the Unix side only, one can send any signal (eg SIGUSR1 ) to the waiting thread with pthread_kill . 仅在Unix方面,可以使用pthread_kill将任何信号(例如SIGUSR1 )发送到等待的线程。 select with then return a negative value, and errno will be set to EINTR . select with,然后返回一个负值,并将errno设置为EINTR But there is nothing like that on the Windows side. 但是在Windows方面没有类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM