免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 20239 | 回复: 15
打印 上一主题 下一主题

再论精确延时(usleep,nanosleep,select) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-06-04 11:06 |只看该作者 |倒序浏览
测试
IBM AIX 3.4 单CPU
        sleep  可以在多线程中使用,只阻塞本线程,不影响所属进程中的其它线程
        不支持 nanosleep
        支持 usleep  和 select
        以下采用 gettimeofday 对 usleep 和 select 的实际精确情况进行测试分析
          function  time(usec)    realTime      reduce
-------------------------------------------------------------------
         usleep         500000     500026         26
         nanosleep      500000   not support
         select         500000     500026         26
         usleep         100000     100021         21
         nanosleep      100000   not support
         select         100000     100025         25
         usleep          50000      50021         21
         nanosleep       50000   not support
         select          50000      50107        107
         usleep          10000      10099         99
         nanosleep       10000   not support
         select          10000      10025         25
         usleep           1000       1021         21
         nanosleep        1000   not support
         select           1000       1024         24
         usleep            900        920         20
         nanosleep         900   not support
         select            900       1024        124
         usleep            500        523         23
         nanosleep         500   not support
         select            500       1024        524
         usleep            100        119         19
         nanosleep         100   not support
         select            100       1023        923
         usleep             10         31         21
         nanosleep          10   not support
         select             10       1024       1014
         usleep              1         19         18
         nanosleep           1   not support
         select              1       1026       1025

       
        由此可以得出,在AIX 3.4下:
                select 只能精确到毫秒级别
                usleep 可以精确到微秒级
                在1毫秒以上,两者的精确度基本一样

同上,在 linux 2.4.20-8smp 双CPU 下测试
          function  time(usec)    realTime      reduce
-------------------------------------------------------------------
         usleep         500000     506453       6453
         nanosleep      500000     509930       9930
         select         500000     499990        -10
         usleep         100000     110023      10023
         nanosleep      100000     109955       9955
         select         100000      99992         -8
         usleep          50000      59971       9971
         nanosleep       50000      59990       9990
         select          50000      50025         25
         usleep          10000      19991       9991
         nanosleep       10000      19988       9988
         select          10000       9956        -44
         usleep           1000      19990      18990
         nanosleep        1000      19989      18989
         select           1000      10024       9024
         usleep            900      20009      19109
         nanosleep         900      19972      19072
         select            900       9943       9043
         usleep            500      19975      19475
         nanosleep         500      19971      19471
         select            500      10012       9512
         usleep            100      19975      19875
         nanosleep         100      19976      19876
         select            100       9943       9843
         usleep             10      19988      19978
         nanosleep          10      19961      19951
         select             10      10011      10001
         usleep              1      19978      19977
         nanosleep           1      19985      19984
         select              1       9932       9931
在 2.4.21-4.ELsmp #1 SMP  4 CPU 下测试
           function  time(usec)    realTime      reduce
-------------------------------------------------------------------
         usleep         500000     501267       1267
         nanosleep      500000     509964       9964
         select         500000     499981        -19
         usleep         100000     109944       9944
         nanosleep      100000     109925       9925
         select         100000      99963        -37
         usleep          50000      59904       9904
         nanosleep       50000      59973       9973
         select          50000      49956        -44
         usleep          10000      19988       9988
         nanosleep       10000      20008      10008
         select          10000      10020         20
         usleep           1000      19988      18988
         nanosleep        1000      19980      18980
         select           1000       9943       8943
         usleep            900      19975      19075
         nanosleep         900      19986      19086
         select            900       9905       9005
         usleep            500      19989      19489
         nanosleep         500      19910      19410
         select            500      10000       9500
         usleep            100      19355      19255
         nanosleep         100      19902      19802
         select            100       9988       9888
         usleep             10      19977      19967
         nanosleep          10      19988      19978
         select             10       9943       9933
         usleep              1      20007      20006
         nanosleep           1      19947      19946
         select              1       9980       9979
         
                由此可以得出如下结论,在 linux 2.4 下:
                        1、支持 usleep,nanosleep,select
                        2、select 的 精确度为 10毫秒。在10毫秒以上很精确
                        3、usleep, nanosleep  很不精确
                同样,通过其它测试程序能得出如下结论:
                        sleep  可以在多线程中使用,只阻塞本线程,不影响所属进程中的其它线程
                                       
                       
               
我只有以上3种测试环境,有其它测试环境的帮我在其它环境下测试一下,将分析结果贴出来。
测试程序在之后发上来

论坛徽章:
0
2 [报告]
发表于 2004-06-04 11:12 |只看该作者

再论精确延时(usleep,nanosleep,select)

/*
        make:  gcc -o test_sleep test_sleep.c
*/
/*        #include  "comm_main.h" */
#include <stdio.h>;
#include <stdlib.h>;
#include <time.h>;
#include <sys/time.h>;
#include <errno.h>;
#include <string.h>;
#include <unistd.h>;
#include <sys/types.h>;

#define PRINT_USEAGE  { \
   fprintf(stderr,"\n Usage: %s usec ",argv[0]); \
   fprintf(stderr,"\n\n";\
  }

int
main (int argc, char **argv)
{
  unsigned int nTimeTestSec = 0;        /* sec */
  unsigned int nTimeTest = 0;        /* usec */
  struct timeval tvBegin;
  struct timeval tvNow;
  int ret = 0;
  unsigned int nDelay = 0;        /* usec */
  fd_set rfds;
  struct timeval tv;
  int fd = 1;
  int i = 0;
  struct timespec req;
  unsigned int delay[20] =
    { 500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0 };
  int nReduce = 0;                /* 误差  */

#if 0
  if (argc < 2)
    {
      PRINT_USEAGE;
      exit (1);
    }
  nDelay = atoi (argv[1]);
#endif

  fprintf (stderr, "%18s%12s%12s%12s\n", "function", "time(usec)", "realTime",
           "reduce";
  fprintf (stderr,
           "-------------------------------------------------------------------\n";

  for (i = 0; i < 20; i++)
    {
      if (delay <= 0)
        break;
      nDelay = delay;

      /*      test usleep */
      gettimeofday (&tvBegin, NULL);
      ret = usleep (nDelay);
      if (-1 == ret)
        {
          fprintf (stderr, " usleep error . errno=%d [%s]\n", errno,
                   strerror (errno));
        }
      gettimeofday (&tvNow, NULL);
      nTimeTest =
        (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -
        tvBegin.tv_usec;
      nReduce = nTimeTest - nDelay;
      fprintf (stderr, "\t usleep       %8u   %8u   %8d\n", nDelay, nTimeTest,
               nReduce);


      /*      test nanosleep */
      gettimeofday (&tvBegin, NULL);
      req.tv_sec = nDelay / 1000000;
      req.tv_nsec = (nDelay % 1000000) * 1000;
      ret = nanosleep (&req, NULL);
      if (-1 == ret)
        {
          fprintf (stderr, "\t nanosleep    %8u   not support\n", nDelay);
        }
      else
        {
          gettimeofday (&tvNow, NULL);
          nTimeTest =
            (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -
            tvBegin.tv_usec;
          nReduce = nTimeTest - nDelay;
          fprintf (stderr, "\t nanosleep    %8u   %8u   %8d\n", nDelay,
                   nTimeTest, nReduce);
        }

      /*      test select */
      gettimeofday (&tvBegin, NULL);
      FD_ZERO (&rfds);
      FD_SET (fd, &rfds);
      tv.tv_sec = 0;
      tv.tv_usec = nDelay;
      ret = select (0, NULL, NULL, NULL, &tv);
      if (-1 == ret)
        {
          fprintf (stderr, " select error . errno=%d [%s]\n", errno,
                   strerror (errno));
        }
      gettimeofday (&tvNow, NULL);
      nTimeTest =
        (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -
        tvBegin.tv_usec;
      nReduce = nTimeTest - nDelay;
      fprintf (stderr, "\t select       %8u   %8u   %8d\n", nDelay, nTimeTest,
               nReduce);

    }

  return 0;
}

论坛徽章:
0
3 [报告]
发表于 2004-06-04 11:39 |只看该作者

再论精确延时(usleep,nanosleep,select)

很好!
建议那些信不过man文档或不愿意看man文档的人,都要象楼主这样自力更生自己测试一下。

论坛徽章:
0
4 [报告]
发表于 2004-06-04 11:55 |只看该作者

再论精确延时(usleep,nanosleep,select)

HP-UX 11 单CPU

          function  time(usec)    realTime      reduce
-------------------------------------------------------------------
         usleep   500000   502950     2950
         nanosleep   500000   509512     9512
         select   500000   509434     9434
         usleep   100000   109658     9658
         nanosleep   100000   109703     9703
         select   100000   109894     9894
         usleep    50000    59515     9515
         nanosleep    50000    59582     9582
         select    50000    59651     9651
         usleep    10000    19755     9755
         nanosleep    10000    19742     9742
         select    10000    17206     7206
         usleep     1000    20455    19455
         nanosleep     1000     7833     6833
         select     1000    11900    10900
         usleep      900    15865    14965
         nanosleep      900     7759     6859
         select      900     9133     8233
         usleep      500    18819    18319
         nanosleep      500     8297     7797
         select      500     9907     9407
         usleep      100    20883    20783
         nanosleep      100     5500     5400
         select      100    10421    10321
         usleep       10    17562    17552
         nanosleep       10    10522    10512
         select       10     8578     8568
         usleep        1    17194    17193
         nanosleep        1    12318    12317
         select        1     6411     6410

论坛徽章:
0
5 [报告]
发表于 2004-06-04 12:08 |只看该作者

再论精确延时(usleep,nanosleep,select)

从feishq贴的测试结果看:
在 HP-UX 11 下 select,usleep,nanosleep 都不能做到精确延时!

有哪位大侠能提供精确延时的方法?

论坛徽章:
0
6 [报告]
发表于 2004-06-04 13:09 |只看该作者

再论精确延时(usleep,nanosleep,select)

硬件中断能精确定时,可那是一般应用程序用的么?
用不严格的测试程序,怎么能测得可靠的结论?

论坛徽章:
0
7 [报告]
发表于 2004-06-04 13:25 |只看该作者

再论精确延时(usleep,nanosleep,select)

我的程序需要做到几百个微秒的延时,请问怎么实现?

论坛徽章:
0
8 [报告]
发表于 2004-06-04 14:20 |只看该作者

再论精确延时(usleep,nanosleep,select)

在多任务环境下,就不可能做到精确定时的,除非你的程序属于系统内核的一部分,你在内核中控制!
要知道你所要求的定时精度已经低于系统时间片了,在你开始计时后停止计时前,系统核心可能把你的任务给置换出去了,再精确的计时又有何意义呢?
如果你是单任务系统,最精确的计时手段就是取CPU时钟周期,然后根据换算得来的总周期数来构造指令。我用这种方法在MCS-51上构造过0.5秒的延时函数。

论坛徽章:
0
9 [报告]
发表于 2004-06-04 14:38 |只看该作者

再论精确延时(usleep,nanosleep,select)

谢谢FH指点迷津!!!

论坛徽章:
0
10 [报告]
发表于 2004-06-04 15:18 |只看该作者

再论精确延时(usleep,nanosleep,select)

我是来看天使的!!呵呵,强人
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP