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
"); 
    }else if(SIGALRM == iSignNo){
        //printf("Capture sign no : SIGALRM
"); 
    }else{
        printf("Capture sign no:%d
",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
");
    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)
", 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)
", left);
    }
    return 0; 
}

void SignHandler(int iSignNo){
    //printTime();
    if(iSignNo == SIGUSR1){
        printf("Capture sign no : SIGUSR1
"); 
    }else if(SIGALRM == iSignNo){
        //printf("Capture sign no : SIGALRM
"); 
    }else{
        printf("Capture sign no:%d
",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
");
    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秒未能执行;

原文地址:https://www.cnblogs.com/yyx1-1/p/6340738.html