关于定时函数usleep的问题,急

battlejoker 2005-07-25 04:24:44
我在一个线程中需要循环从一个缓冲区内读取数据
在每次循环结束后,将线程挂起一段时间
但为了提高实时性,挂起的时间又不能太长
按照man page里的介绍usleep( int n )应该可以休眠n个microsecond
但是我写了个小程序做了一下测试,结果休眠的时间确远大于microsecond数量级,不知道是为什么

测试程序如下:
int main(void)
{

for (int counter = 0; counter <= 1000; counter++)
{
printf("%d\n", counter);
usleep(10);
}

return 0;
}

屏幕打印的结果说明循环的速度很低
我还试过用select定时,也出现了类似的问题……
这是什么原因?
...全文
3132 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjlsmail 2005-11-02
  • 打赏
  • 举报
回复
Mark and Study
battlejoker 2005-07-27
  • 打赏
  • 举报
回复
select精度大概也是在10ms左右
battlejoker 2005-07-26
  • 打赏
  • 举报
回复
一般在Linux下有哪些能够阻塞线程的方法呢?
第一次在Linux下做开发,真是挠头啊……
ks9960 2005-07-26
  • 打赏
  • 举报
回复
用select实现100ms左右的精度应该还是可以的,如果在高的精确度估计就需要使用cpu时钟了,网上有windows的例子,linux下如何取不清楚。我觉得楼主应该考虑自己的设计,应该可以实现为阻塞读取。
happykevinxing 2005-07-26
  • 打赏
  • 举报
回复
在多任务系统要达到那么高的精度是有点困难的,你可以采用系统定时试试,usleep和sleep很不精确的.
clicksoft 2005-07-26
  • 打赏
  • 举报
回复
用select把
void MTimeOuts(int msec)
{
struct timeval timeout;

memset(&timeout, 0, sizeof(struct timeval));
if(msec >= 1000)
{
timeout.tv_sec = msec/1000;
timeout.tv_usec = 0;
}
else
{
timeout.tv_sec = 0;
timeout.tv_usec = msec;
}

select(0, NULL, NULL, NULL, &timeout);
}
coonzhang 2005-07-26
  • 打赏
  • 举报
回复
usleep 的最小精度好像是10毫秒吧
battlejoker 2005-07-26
  • 打赏
  • 举报
回复
我找到相关资料了,多谢
battlejoker 2005-07-26
  • 打赏
  • 举报
回复
信号量支持多个进程之间的访问同步控制,多线程可以么?
ks9960 2005-07-26
  • 打赏
  • 举报
回复
这个就是楼主需要做的工作了吧。
你的缓冲区是什么了,比如是fd,或者队列什么的,根据实际情况查看相应的资料。
battlejoker 2005-07-25
  • 打赏
  • 举报
回复
了解
那应该采用何种技术才能实现我想要的功能呢?
ks9960 2005-07-25
  • 打赏
  • 举报
回复
你的精确度要求这么高,而你的代码运行的时间都超过了你的挂起时间了。
#include <unistd.h>
#include <sys/time.h>

int main(void)
{
int counter;
unsigned long totalSpec=0;
struct timeval tvBeg, tvEnd;

for (counter=0; counter < 100; counter++)
{
gettimeofday(&tvBeg, NULL);
usleep(1000);
gettimeofday(&tvEnd, NULL);
totalSpec += tvEnd.tv_usec-tvBeg.tv_usec;
printf("%d\n", tvEnd.tv_usec-tvBeg.tv_usec);
}
printf("try to usleep 1000 us 100 times, average of result is: %ld\n",
totalSpec/100);

return 0;
}
2972
3855
3913
3878
3899
3893
3896
3896
3895
3907
3885
3896
3896
3896
3900
3893
3895
3896
3897
3898
3893
3896
3897
3896
3898
3890
3903
3903
3903
3914
3893
3903
11458
2198
3902
3903
......
重这段代码运行结果来看的话,两次gettimeofday运行花费时间在1000-1500us左右,usleep在此时的睡眠时间还是基本准确的。
当把usleep(1000)一句中1000改为更小的数值时,运行结果没有明显变化,说明usleep不能提供小于1000us的更小的精度了,而这也与linux的时间片以ms为单位的说法符合。
当把usleep(1000)一句中1000改为更大的数值10000时,结果如下,也是正确的。3个函数调用所花时间加上睡眠的10000us
13623
13660
13662
13669
13654
13662
13659
13668
13668
13670
13666
13668
13668
13668
.....
yyy790601 2005-07-25
  • 打赏
  • 举报
回复
linux中用的是时间片轮转算法,进程轮训要消耗时间,转换到一个进程来执行要消耗时间。结果在进程睡眠和运行过程中,许多时间已经过去了。

我是这样理解的。期待权威的说法。

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧