一、介紹
sleep()低精度休眠,精度是秒 ,可以被信號中斷,如果被信號中斷返回剩餘秒數。所以sleep,alarm,setitimer 最好不要結合使用
nanosleep()高精度休眠,精度是納秒,也是可以被信號中斷。
二、函數接口
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
參數:
seconds:秒數
返回值:
正常休眠結束返回0,如果被信號中斷,返回剩餘秒數
#include <time.h>
int nanosleep(const struct timespec *request, struct timespec *remain);
參數:
req: struct timespec類型指針,設置休眠的時間
remain:若remain不爲NULL,那麼指針指向的緩衝區返回剩餘的休眠時間,可以利用
這一返回值重啓系統調用完成休眠
返回值:
如果被信號中斷返回-1,並設置errno爲EINTR.
注意:雖然nanosleep 精度很高,但是還是受到軟件時鐘間隔大小影響,
假設一個間隔是19毫秒的定時器,如果jiffy(軟時鐘週期)是4毫秒,時器實際上會每隔20毫秒
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
三、實例sleep
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <utime.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <malloc.h>
#include <signal.h>
#include <setjmp.h>
#include <stdarg.h>
void errExit(char * msg)
{
printf("%s\n",msg);
exit(EXIT_FAILURE);
}
static void sigintHandler(int sig)
{
printf("\n");
return; /* Just interrupt nanosleep() */
}
int main(int argc, char *argv[])
{
struct timeval start, finish;
struct timespec request, remain;
struct sigaction sa;
int s;
char *endptr;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sigintHandler;
if (sigaction(SIGINT, &sa, NULL) == -1)
errExit("sigaction");
if (gettimeofday(&start, NULL) == -1)
errExit("gettimeofday");
s = 10;
for (;;) {
s = sleep(s);
if (gettimeofday(&finish, NULL) == -1)
errExit("gettimeofday");
printf("Slept for: %9.6f secs\n", finish.tv_sec - start.tv_sec +
(finish.tv_usec - start.tv_usec) / 1000000.0);
if (s == 0)
break; /*sleep() completed */
}
printf("sleep complete\n");
return 0;
}
yexiang@ubuntu:<_Sys>$ ./a.out
^C
Slept for: 1.544438 secs
^C
Slept for: 4.797223 secs
^C
Slept for: 8.250651 secs
sleep complete
四、實例nanosleep
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <utime.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <malloc.h>
#include <signal.h>
#include <setjmp.h>
#include <stdarg.h>
void errExit(char * msg)
{
printf("%s\n",msg);
exit(EXIT_FAILURE);
}
static void sigintHandler(int sig)
{
printf("\n");
return; /* Just interrupt nanosleep() */
}
int main(int argc, char *argv[])
{
struct timeval start, finish;
struct timespec request, remain;
struct sigaction sa;
int s;
char *endptr;
if (argc != 3)
{
printf("arg error!!!\n");
return -1;
}
request.tv_sec = strtol(argv[1],&endptr,10);
request.tv_nsec = strtol(argv[2],&endptr,10);
/* Allow SIGINT handler to interrupt nanosleep() */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sigintHandler;
if (sigaction(SIGINT, &sa, NULL) == -1)
errExit("sigaction");
if (gettimeofday(&start, NULL) == -1)
errExit("gettimeofday");
for (;;) {
s = nanosleep(&request, &remain);
if (s == -1 && errno != EINTR)
errExit("nanosleep");
if (gettimeofday(&finish, NULL) == -1)
errExit("gettimeofday");
printf("Slept for: %9.6f secs\n", finish.tv_sec - start.tv_sec +
(finish.tv_usec - start.tv_usec) / 1000000.0);
if (s == 0)
break; /* nanosleep() completed */
printf("Remaining: %2ld.%09ld\n", (long) remain.tv_sec, remain.tv_nsec);
request = remain; /* Next sleep is with remaining time */
}
printf("nanosleep complete\n");
return 0;
}
yexiang@ubuntu:<_Sys>$ ./a.out 10 0
^C
Slept for: 0.840907 secs
Remaining: 9.160336222
^C
Slept for: 1.493969 secs
Remaining: 8.514564300
^C
Slept for: 2.336717 secs
Remaining: 7.672307150
^C
Slept for: 5.207743 secs
Remaining: 4.801948215
^C
Slept for: 6.730377 secs
Remaining: 3.279686072
^C
Slept for: 8.778798 secs
Remaining: 1.231587032
Slept for: 10.010956 secs
nanosleep complete