Linux Networking IO Noob:选择()和Recvfrom,阻塞还是非阻塞?

时间:2013-06-15 02:31:13

标签: c++ c sockets udp

我继承了一段从UDP套接字读入数据的代码。我需要一些帮助来弄清楚这里发生了什么,以及我是否可以改善任何性能。

代码首先调用select(),然后调用recvfrom()。根据我的研究,似乎只有在select()返回有可用数据的事实时才会调用recvfrom()。此代码基本上由一个持续侦听多播消息的线程组成。因此,它基本上位于select()例程中,直到它接收数据或超时。

我想知道是否有更好的方法来改进此代码的性能。首先,select()是否必要?基于这个线程:setting timeout for recv fcn of a UDP socket我似乎可以设置recvfrom()命令本身的超时。这会给我买什么吗?另外,根据一些研究,我见过很多没有select()的实现。这是为什么?

另外,理想情况下,我想释放尽可能多的CPU。有没有办法可以让进程在收到数据包之前进入睡眠状态?话虽如此,为了简单起见,我希望一次收到一个完整的数据包。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

recvfrom阻止或select等待某个事件时,该过程实际上是睡着了;也就是说,它没有安排运行。因此,您现有的代码(至少如果我正确地解释您的描述)已经满足您的第一个要求。

  

有没有办法可以让进程在收到数据包之前进入休眠状态?

UDP是“数据报包服务”。 (引自man 7 udp)。也就是说,它总是发送和接收完整的数据包。因此,使用UDP,您永远不必担心第二个要求:

  

为了简单起见,我希望一次收到一个完整的数据包。

总而言之,我会说你没有问题。

但是,假设您能够select() setsocketopt()(您可能可以执行此操作),您可以删除SO_RCVTIMEO调用,如果它仅等待单个描述符虽然Posix允许单个实现不允许设置选项,但是没有绝对的保证。)我怀疑你是否会注意到这样做会带来任何性能提升,但它应该可以节省几微秒。

答案 1 :(得分:1)

  

有没有办法可以让进程在收到数据包之前进入休眠状态?

你已经这样做了。这就是select()在阻塞模式下执行或recvfrom()的行为。

  

为了简单起见,我希望一次收到一个完整的数据包。

这就是UDP已经在为你做的事了。

答案 2 :(得分:0)

可能会有所帮助:10k problem

答案 3 :(得分:0)

I can just set the timeout of the recvfrom() command itself

如果select只等待一个文件描述符(例如socket),那么与你的建议没什么区别。但如果管理不止一个,那么就没有更好的解决方案。