select() 是不是可以实现单套接字读/写超时?

Posted

技术标签:

【中文标题】select() 是不是可以实现单套接字读/写超时?【英文标题】:Is select() Ok to implement single socket read/write timeout?select() 是否可以实现单套接字读/写超时? 【发布时间】:2010-03-15 08:40:52 【问题描述】:

我有一个应用程序处理阻塞调用的网络通信。每个线程管理一个连接。我在套接字上读取或写入之前使用 select 添加了读取和写入操作的超时。

众所周知,Select 在处理大量套接字时效率低下。但是,就性能而言,是否可以将它与单个套接字一起使用,或者是否有更有效的方法来为单个套接字调用添加超时支持? select 的好处是可移植。

【问题讨论】:

【参考方案1】:

是的,没问题,您确实需要一些超时机制,以免从行为不端的客户端等泄漏资源。

请注意,拥有大量线程比使用 select 处理大量套接字效率更低。

【讨论】:

谢谢。我计划使用 libev 来处理多个并发通信渠道。在这个阶段,我只考虑一个线程访问一个套接字。【参考方案2】:

如果您认为 select 在处理大量套接字时效率低下,请尝试使用每个套接字一个线程来处理大量套接字。你进入了一个痛苦的世界。就像你在扩展到 1000 个线程时会遇到问题。

我过去所做的是:

以 X (512, 1024) 为一组对套接字进行分组。 让一个或两个线程沿着这些组运行并选择 () - 然后将带有新数据的套接字移交给队列。 有许多工作线程使用新数据处理这些套接字。多少取决于我需要多少 CPU 最大化;)

这样,我不会使用带有大量项目的超级 über select (),而且我也不会在线程上浪费可笑的内存量(提示:每个线程都需要它自己的堆栈。只有 2mb,即 2gb 用于 1000 个套接字- 谈论低效)并浪费大量 CPU 进行无用的上下文切换。

【讨论】:

【参考方案3】:

线程/选择的问题是您是否想避免客户端相互阻塞。如果这不是问题,那么单线程工作。如果是,请选择适当的线程方案(每个连接 1 个线程、每个连接的工作线程、每个请求的工作线程……)。

当每个连接使用 1 个线程时,每次读/写选择是一个不错的解决方案,但一般来说,最好将非阻塞套接字与选择结合使用,以避免在只有一部分的情况下阻塞预期的消息到达,然后在写入后进行选择。

【讨论】:

以上是关于select() 是不是可以实现单套接字读/写超时?的主要内容,如果未能解决你的问题,请参考以下文章

C++ Boost ASIO:如何读取/写入超时?

什么叫套接字超时~

通过select监控多个描述符实现并发连接

在读取缓冲区已满时使用 select 检查可写套接字

Unix网络编程 高级IO套接字设置超时

epoll/select 用于互斥体/信号量