0

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

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

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

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

在此先感谢您的帮助。

4

4 回答 4

2

recvfrom阻塞或select等待事件时,进程实际上处于睡眠状态;也就是说,它没有计划运行。因此,您现有的代码(至少如果我正确解释了您的描述)已经满足您的第一个要求。

有没有办法让进程进入睡眠状态,直到它收到一个数据包?

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

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

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

但是,select()如果它只等待一个描述符,假设您能够删除调用setsocketopt() SO_RCVTIMEO(您可能可以这样做,尽管 Posix 允许单个实现不允许设置该选项,那么您可能能够删除该调用,所以有不是绝对的保证。)我怀疑你是否会注意到这样做的任何性能改进,但它应该可以节省几微秒。

于 2013-06-15T06:34:48.770 回答
1

有没有办法让进程进入睡眠状态,直到它收到一个数据包?

你已经在这样做了。这就是 select() 所做的,或者是阻塞模式下的 recvfrom() 。

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

这就是 UDP 已经为您做的事情。

于 2013-06-15T07:19:00.810 回答
0

可能这会有所帮助:10k 问题

于 2013-06-15T07:15:30.193 回答
0
I can just set the timeout of the recvfrom() command itself

如果 select 只等待一个文件描述符(例如套接字),那么与您的建议没有太大区别。但是,如果它管理的不止一个,那么就没有更好的解决方案了。

于 2013-08-04T20:34:11.277 回答