Linux下 sleep函数的注意事项
1. 休眠sleep(unsigned int)为线程内操作
所以如果不同线程,信号量SIGALRM是不能中断sleep();
编写程序进行测试
//timercreate_demo.cpp #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> #include <pthread.h> void SignHandler(int iSignNo); void testTimerSign(); void printTime(); void *function(void *arg); int main() { pthread_t thread1; pthread_create(&thread1,NULL,function,(char*)"111"); testTimerSign(); while(true); return 0; } void SignHandler(int iSignNo){ if(iSignNo == SIGUSR1){ printf("Capture sign no : SIGUSR1\n"); }else if(SIGALRM == iSignNo){ //printf("Capture sign no : SIGALRM\n"); }else{ printf("Capture sign no:%d\n",iSignNo); } } void testTimerSign(){ struct sigevent evp; struct itimerspec ts; timer_t timer; int ret; evp.sigev_value.sival_ptr = &timer; evp.sigev_notify = SIGEV_SIGNAL; evp.sigev_signo = SIGALRM; signal(evp.sigev_signo, SignHandler); ret = timer_create(CLOCK_REALTIME, &evp, &timer); if(ret) { perror("timer_create"); } ts.it_interval.tv_sec = 1; ts.it_interval.tv_nsec = 0; ts.it_value.tv_sec = 1; ts.it_value.tv_nsec = 0; printTime(); printf("start\n"); ret = timer_settime(timer, 0, &ts, NULL); if(ret) { perror("timer_settime"); } } void printTime(){ struct tm *cursystem; time_t tm_t; time(&tm_t); cursystem = localtime(&tm_t); char tszInfo[2048] ; sprintf(tszInfo, "%02d:%02d:%02d", cursystem->tm_hour, cursystem->tm_min, cursystem->tm_sec); printf("[%s]",tszInfo); } void *function(void *arg){ char *m; m = (char *)arg; while(true) { while(true){ int left = sleep(3); printTime(); printf("sleep(3)(left=%d)\n", left); } } }
可以看出,在主线程的定时器中的信号量SIGALRM是无法中断子线程thread1的休眠;
在同一线程中, sleep()函数会被SIGALARM信号中断
使用SIGALRM信号量定时
上面程序中使用了信号量SIGUSR1;
如果使用信号量SIGALRM;
(对 CLOCK_REALTIMER来说,默认信号就是SIGALRM)
sleep()函数使用的就是实时时钟CLOCK_REALTIMER
所以使用信号值SIGALRM会中断sleep(int second)函数的休眠;
//timercreate_demo.cpp #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> void SignHandler(int iSignNo); void testTimerSign(); void printTime(); int main() { testTimerSign(); while(true){ int left = sleep(5); printTime(); printf("sleep(5)(left=%d)\n", left); } return 0; } void SignHandler(int iSignNo){ //printTime(); if(iSignNo == SIGUSR1){ printf("Capture sign no : SIGUSR1\n"); }else if(SIGALRM == iSignNo){ //printf("Capture sign no : SIGALRM\n"); }else{ printf("Capture sign no:%d\n",iSignNo); } } void testTimerSign(){ struct sigevent evp; struct itimerspec ts; timer_t timer; int ret; evp.sigev_value.sival_ptr = &timer; evp.sigev_notify = SIGEV_SIGNAL; evp.sigev_signo = SIGALRM; signal(evp.sigev_signo, SignHandler); ret = timer_create(CLOCK_REALTIME, &evp, &timer); if(ret) { perror("timer_create"); } ts.it_interval.tv_sec = 1; ts.it_interval.tv_nsec = 0; ts.it_value.tv_sec = 1; ts.it_value.tv_nsec = 0; printTime(); printf("start\n"); ret = timer_settime(timer, 0, &ts, NULL); if(ret) { perror("timer_settime"); } } void printTime(){ struct tm *cursystem; time_t tm_t; time(&tm_t); cursystem = localtime(&tm_t); char tszInfo[2048] ; sprintf(tszInfo, "%02d:%02d:%02d", cursystem->tm_hour, cursystem->tm_min, cursystem->tm_sec); printf("[%s]",tszInfo); }
因为timer_settime()中定时器间隔时间为1秒
于是sleep(5)每次都被打断不能按时休眠,剩余4秒未能执行;
路之遥