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

时间:2010-05-27 13:13:26

标签: c debian

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

谢谢,

Danny Llewallyn

5 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

假设您提到的其他评论者所采用的更高级别方法是不可用的,那么嵌入式/微控制器领域的一种常见方法是创建所需长度的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

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

而不是在数据包级别执行操作,而不必担心超出接收方等问题。为什么不使用TCP流来传输数据?让TCP处理流量控制和数据包重传等事情。

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