我继承了一段从UDP套接字读入数据的代码。我需要一些帮助来弄清楚这里发生了什么,以及我是否可以改善任何性能。
代码首先调用select(),然后调用recvfrom()。根据我的研究,似乎只有在select()返回有可用数据的事实时才会调用recvfrom()。此代码基本上由一个持续侦听多播消息的线程组成。因此,它基本上位于select()例程中,直到它接收数据或超时。
我想知道是否有更好的方法来改进此代码的性能。首先,select()是否必要?基于这个线程:setting timeout for recv fcn of a UDP socket我似乎可以设置recvfrom()命令本身的超时。这会给我买什么吗?另外,根据一些研究,我见过很多没有select()的实现。这是为什么?
另外,理想情况下,我想释放尽可能多的CPU。有没有办法可以让进程在收到数据包之前进入睡眠状态?话虽如此,为了简单起见,我希望一次收到一个完整的数据包。
提前感谢您的帮助。
答案 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),那么与你的建议没什么区别。但如果管理不止一个,那么就没有更好的解决方案。