首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用select()然后read()与阻塞read()循环

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

Stack Overflow用户
提问于 2015-03-17 19:21:41
回答 2查看 3.8K关注 0票数 6

我正在处理一个多线程服务器代码,其中我创建了两个线程,这些线程在accept()之后与阻塞的TCP套接字交互。

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

但是,我的同事告诉我,我不应该用read做一个with循环,因为它会浪费CPU周期(这是一个阻塞的read,内核不让线程休眠吗?),我应该使用select()系统调用,然后读取套接字。

假设读取线程是错误的吗?哪种方法更好?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-17 20:12:46

在I/O上阻塞线程时,线程不消耗CPU,这是正确的。

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

至于是喜欢在read()上阻塞还是在select() (或poll())上阻塞来管理单个通道,这有点像苹果和橘子之间的比较,但是如果这些是选择,那么在read()上阻塞就更简单了。那就是我会做的。苹果与苹果的比较将更沿着多线程或子进程的路线进行,每个进程在read()上阻塞一个不同的通道,而一个进程的一个线程在select()的帮助下管理多个通道。

票数 5
EN

Stack Overflow用户

发布于 2015-03-17 19:44:00

如你朋友所建议的那样,环顾四周看看是否有数据并不是一种很好的方法。浪费CPU时间。这种方法称为轮询,这是一种效率低下的方法。

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

因此,与线程检查数据是否连续可用不同,TCP将在有数据时通知您。

希望它清晰

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29107904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档