《Linux系統調用:sleep,nanosleep》

一、介紹

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

 

發佈了428 篇原創文章 · 獲贊 147 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章