为什么nanosleep()和usleep()太慢了?

我有一个程序,生成数据包发送到接收器。 我需要一种有效的方法,在每个数据包的发送之间引入一个小延迟,以免超出接收器。 我试过usleep()和nanosleep(),但它们似乎太慢了。 我已经实现了一个繁忙的等待循环并取得了更大的成功,但我知道这不是最有效的方法。 我对任何人尝试做我正在做的事情感兴趣。 其他人是否发现usleep()和nanosleep()能够很好地适用于此类应用?

谢谢,

Danny Llewallyn

睡眠函数在非常小的时间间隔内的行为在很大程度上取决于内核版本和配置。

如果你有一个“无滴答”内核( CONFIG_NO_HZ )和高分辨率的定时器,那么你可以期待睡眠非常接近你所要求的。

否则,您通常会以定时器中断的粒度结束睡眠。 定时器中断间隔是可配置的( CONFIG_HZ ) – 10ms,4ms,3.3ms和1ms是常见的选择。

假设您提到的其他评论者所采用的更高级别方法是不可用的,那么嵌入式/微控制器领域的一种常见方法是创建所需长度的NOP循环。

NOP操作占用一个CPU周期,在嵌入式环境中,您通常可以确切地知道处理器正在运行的时钟速度,因此您只需使用简单的for-loop conatining _NOP()或者如果只需要非常短的延迟,那么就不要打扰一个循环,只需添加所需的nops数。

 regTX = 0xFF; // Transmit FF on special register // Wait three clock cycles _NOP(); _NOP(); _NOP(); regTX = 0x00; // Transmit 00 

这似乎是一个糟糕的设计。 理想情况下,接收器会对它接收的任何额外数据进行排队,然后将其消息处理为单独的线程。 通过这种方式,它可以处理数据突发,而无需依赖发送方来限制其请求。

但是,如果(例如)您无法控制接收器的代码,或者这是一个嵌入式应用程序,也许这种方法是不实用的。

我可以在这里代表Solaris,因为它使用OS定时器来唤醒睡眠调用。 默认情况下,无论您在usleep指定了什么,最短等待时间都将为10毫秒。 但是,您可以在/etc/system配置文件中使用参数hires_tick = 1 (1ms wakeups)和hires_hz =来增加定时器唤醒调用的频率。

而不是在数据包级别做事情,你需要担心超越接收者这样的事情。 为什么不使用TCP流来传输数据? 让TCP处理流量控制和数据包重传等事情。

如果您已经在分组化方法上投入了大量资金,则可以始终在TCP上使用层来从TCP流中提取原始数据包,并将这些数据包提供给现有函数。