在同一进程的不同线程中使用select()的成本

时间:2011-08-17 14:33:10

标签: c select

在我的应用程序中,我开始在多个位置使用select()调用,监视我的进程中的不同内容(网络连接,IPC,消息传递,文件......)。 所有调用都使用他们的自己的文件描述符集,这意味着在选择中不会使用两次描述符。

这意味着有时候我会在不同的线程中阻塞5个select()个调用。

在不同的线程中多次使用select()是否存在性能损失,而不是仅使用一个调用并将结果分派给相应的线程?

实际上,一次待处理的select()来电数量是否有限制?

有没有衡量这个的工具?

由于应用程序可能会变得更大,我怀疑在某些时候,如果这开始出现问题,我将不得不编写某种集中的select()代码来收集所有要监视和通知的FD准备好收集/写入数据时的客户端线程。

所以我想我以前最好问...

2 个答案:

答案 0 :(得分:3)

您不会注意到任何性能差异。

在内核中,select将您的线程添加到您正在选择的每个描述符的“等待队列”并将其置于休眠状态。如果选择n描述符,则会将线程添加到n等待队列。当描述符发生可轮询的事情(例如,数据到达套接字)时,该等待队列上的所有线程都会被唤醒。

选择大量描述符会将您添加到大量的等待队列中。一旦被唤醒,您的线程将不得不从所有等待队列中删除,包括那些没有活动的队列。所以在这方面,等待多个线程中的一小组描述符而不是一个线程中的大量描述符可能会有一些小的好处。

另一方面,select本身要求内核循环通过所有可能的描述符来查看哪些是fd_set的成员。所以在这方面,只有一个线程可以进行select调用......

总的来说,我猜它是一种清洗。

如果要处理大量描述符,最好使用更加可扩展(尽管不可移植)的机制,如epoll。使用epoll,每个处理描述符池的多个线程应该可以很好地扩展。

答案 1 :(得分:0)

应该在操作系统中处理选择调用,正如您所说 - 它的阻塞,而不是轮询 - 因此它不会对您的应用程序造成性能损失。除了操作系统一般可以打开的文件描述符数量限制外,我也不相信使用它会有任何限制,这与select无关。