【发布时间】:2012-09-06 09:13:41
【问题描述】:
使用select()函数有什么用吗?
根据我的(小)经验,我倾向于相信线程就足够了。
所以我想知道,对于还不了解线程的人来说,select() 只是一个教学工具吗?
【问题讨论】:
标签: c sockets client-server
使用select()函数有什么用吗?
根据我的(小)经验,我倾向于相信线程就足够了。
所以我想知道,对于还不了解线程的人来说,select() 只是一个教学工具吗?
【问题讨论】:
标签: c sockets client-server
考虑以下示例。您有一个中等繁忙的 Web 服务器,连接数大约为 100K。您没有使用select 或类似的东西,因此每个连接只有一个线程,这意味着 100K 线程很快就会成为问题。
即使你调整你的系统直到它允许这样的怪物,大多数线程只会在一个套接字上等待。如果有一种机制可以在套接字变得有趣时通知您,那不是更好吗?
换句话说,线程和select-like 机制是互补的。你不能用threads 来代替select 所做的简单事情:监控文件描述符。
【讨论】:
select 循环将任务推送到线程池中。
到目前为止,单线程轮询更易于使用、实施和(最重要的是)理解。并发编程为您的项目增加了巨大的智力成本:同步数据很棘手且容易出错,锁定会带来许多错误机会,无锁数据结构会导致性能下降,并且程序流变得难以在心理上可视化(或“序列化”)也许)。
相比之下,单线程轮询(可能使用epoll/kqueue 而不是select)通常会为您提供非常好的性能(当然取决于您响应数据的具体操作),同时保持直截了当。
特别是在 Linux 中,您可以拥有 timerfds、eventfds、signalfds 和 inotify-fds,以及嵌套的 epoll-fds,它们都位于您的轮询集中,为您提供了一种非常统一的方式来处理各种“异步”事件。如果最终您需要更高的性能,您可以通过同时运行多个轮询器来获得单点并行性,并且大部分数据同步由内核为您完成,它保证只有一个线程接收如果准备就绪,则投票成功。
【讨论】: