使用select()然后read()vs阻塞read()循环

时间:2015-03-17 19:21:41

标签: c multithreading sockets

我正在研究一个多线程服务器代码,我创建了2个线程,它们在accept()之后与阻塞的TCP套接字进行交互。

线程#1检查是否有来自msg队列的命令并将其写入套接字。线程#2只是一个简单的while循环,调用read然后阻塞,如果没有数据准备好被读取。

然而,我的同事告诉我,我不应该使用read进行while循环,因为它会浪费CPU周期(它是阻塞read,不会内核放入线程要睡觉?),我应该使用select()系统调用然后读取套接字。

假设读取线程我是否不正确?哪种方法更好?

2 个答案:

答案 0 :(得分:2)

在I / O上阻塞时,线程不会占用CPU。

select()系统调用是一种可行的替代方案,但其主要用例是从/向多个通道多路复用I / O.在这种情况下,一个线程通过阻塞读取(或写入)来服务所有通道是不可行的,因为它经常被阻塞等待来自一个通道的数据而另一个通道阻塞数据就绪并等待。另一方面,您不希望在循环中执行非阻塞读取,因为浪费CPU。

至于是否更喜欢阻止read()或阻止select()(或poll())管理单个频道,这有点像苹果到橙子的比较,但是如果这些是选择,则阻止read()更直接。这就是我要做的。苹果对苹果的比较更多的是多线程或子进程,每个线程在read()阻塞不同的通道,而一个进程的一个线程在{{1}的帮助下管理多个通道}}

答案 1 :(得分:-3)

如朋友建议的那样,循环查看是否有数据并不是一种好方法。这浪费了CPU时间。这种方法称为轮询,这是一种低效的方法

相反,Read应该是事件驱动的。这意味着在有可读数据之前,Read线程根本不会运行。 所以,你朋友建议的是正确的。你应该转向事件驱动模型。这个所谓的Select()调用的作用是,它告诉TCP堆栈通知读取线程,何时有可用的数据。

因此,不是您的线程检查数据是否可以连续使用,TCP会在有数据时通知您。

希望明确