Chinaunix

标题: 关于nanosleep [打印本页]

作者: apony    时间: 2007-10-15 10:13
标题: 关于nanosleep
nanosleep可以很好的保留中断时剩余时间,可以提高较精确的sleep。

#include <errno.h>
#include <time.h>
#include <signal.h>
void signal_int(int signo)
{
        printf("signal:%d\n", signo);
}
int better_sleep (double sleep_time)
{
struct timespec tv;
/* Construct the timespec from the number of whole seconds... */
tv.tv_sec = (time_t) sleep_time;
/* ... and the remainder in nanoseconds. */
tv.tv_nsec = (long) ((sleep_time - tv.tv_sec) * 1e+9);
while (1)
{
  /* Sleep for the time specified in tv. If interrupted by a
    signal, place the remaining time left to sleep back into tv. */
  int rval = nanosleep (&tv, &tv);
  if (rval == 0)
   /* Completed the entire sleep time; all done. */
   return 0;
  else if (errno == EINTR)
   /* Interrupted by a signal. Try again. */
   continue;
  else
   /* Some other error; bail out. */
   return rval;
}
return 0;
}

int main(int argc, char** argv)
{
        signal(SIGINT, signal_int);
        better_sleep(10);
}
作者: xiaozhu2007    时间: 2007-10-15 11:47
标题: 学习下呵呵
#include <errno.h>
#include <time.h>
#include <signal.h>

static void signal_int(int signo);
static int better_sleep (double sleep_time);

int main(int argc, char* argv[])
{
        signal(SIGINT, signal_int);
        better_sleep(10);
}

static int better_sleep (double sleep_time){
        struct timespec                 tv;
        struct timespec                 tv_rval;
        int                             rval;

        int                             rval;

        /* Construct the timespec from the number of whole seconds... */
        tv.tv_sec = (time_t) sleep_time;
        /* ... and the remainder in nanoseconds. */
        tv.tv_nsec = (long) ((sleep_time - tv.tv_sec) * 1e+9);

        printf("tv.tv_sec = %d\n", tv.tv_sec);
        printf("tv.tv_nsec = %ld\n", tv.tv_nsec);

        while (1){
                /* Sleep for the time specified in tv. If interrupted by a
                signal, place the remaining time left to sleep back into tv. */

                int rval = nanosleep (&tv, &tv_rval);
                if (rval == 0){
                        /* Completed the entire sleep time; all done. */
                        printf("have passed sleep time.\n");
                        return 0;
                }
                else if (errno == EINTR){
                        /* Interrupted by a signal. Try again. */
                        printf("have received by interruped signal.\n");
                        printf("tv_rval.tv_sec = %d\n", tv_rval.tv_sec);
                        printf("tv_rval.tv_nsec = %ld\n");
                        return rval;
                }
                else{
                        /* Some other error; bail out. */
                        perror("nanosleep");
                        return rval;
                }
        }

        return 0;
}

static void signal_int(int signo)
{
        printf("signal:%d\n", signo);
}
简单修改了一下代码,调试学习下呵呵.
现在有个问题:gcc test.c -lrt后运行程序,在还没有到10s的时候,ctrl+c中断程序,程序将会打印tv_rval结构体的成员值,为什么打印的结果始终都是tv_rval.tv_sec等于tv_rval.tv_nsec的值呢?也就是说纳秒数打印不了.


另外:man  nanosleep:
DESCRIPTION
     The nanosleep() function causes the current thread
      to be suspended from execution until either the time inter-
     val  specified  by the rqtp argument has elapsed or a signal
     is delivered to the calling thread  and  its  action  is  to
     invoke  a  signal-catching function or to terminate the pro-
     cess. The suspension  time  may  be  longer  than  requested
     because  the argument value is rounded up to an integer mul-
     tiple of the sleep resolution or because of  the  scheduling
     of other activity by the system. But, except for the case of
     being interrupted by a signal, the suspension time will  not
     be  less than the time specified by rqtp, as measured by the
     system clock, CLOCK_REALTIME.

     The use of the nanosleep() function has  no  effect  on  the
     action or blockage of any signal.
我英语不好,其中这一句说的是什么意思:
The suspension  time  may  be  longer  than  requested
     because  the argument value is rounded up to an integer mul-
     tiple of the sleep resolution or because of  the  scheduling
     of other activity by the system.
作者: apony    时间: 2007-10-15 17:04
标题: 回复 #2 xiaozhu2007 的帖子
看看你printf的参数...

大体意思:暂停的时间可能会比要求的多些,主要由于参数近似计算或进程间调度延迟导致.
作者: xiaozhu2007    时间: 2007-10-16 00:07
struct timespec {
                  time_t tv_sec;        /* seconds */
                  long   tv_nsec;       /* nanoseconds */
              };

纳秒数不是long  int 类型的吗?怎么打印呢?


还有:fedora7下:man  nanosleep
DESCRIPTION
       nanosleep()  delays  the execution of the program for at least the time
       specified in *req.  The function can return earlier  if  a  signal  has
       been  delivered to the process. In this case, it returns -1, sets errno
       to EINTR, and writes the remaining time into the structure  pointed  to
       by  rem unless rem is NULL.  The value of *rem can then be used to call
       nanosleep() again and complete the specified pause.
里面有这一句:The value of *rem can then be used to call
       nanosleep() again and complete the specified pause.在这个程序中当10秒内
产生中断信号时,*rem保存的是sleep剩下的时间,那么*rem是如何call nansleep again的呢?

请指点,谢谢!
作者: apony    时间: 2007-10-16 10:02
你的printf("tv_rval.tv_nsec = %ld\n");第二个参数呢?打印空的?
测试程序中while中的调用就是为了call nanosleep again
作者: xiaozhu2007    时间: 2007-10-16 10:44
标题: 回复 #5 apony 的帖子
哎,没 看 到printf没加参数,白痴阿

作者: abc3214    时间: 2012-08-24 19:53
第二个参数呢?打印空的




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2