zoukankan      html  css  js  c++  java
  • 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秒未能执行;

  • 相关阅读:
    Nginx 提示500 ,设置提示具体错误
    部署laravel 到linux环境
    php & vue 跨域问题解决方案
    一个php学习vue技术(篇章1)
    中年危机
    elasticsearch 创建索引、unassigned、elasticsearch 创建索引后出现unassigned、
    laravel jwt 报错 Argument 3 passed to LcobucciJWTSignerHmac::doVerify() must be an instance of LcobucciJWTSignerKey, null given
    laravel jwttoken jwt attempt laravel auth->attempt() 返回false
    composer 报错 Carbon 1 is deprecated, see how to migrate to Carbon 2
    php 服务端主动向客户端推送消息, php swoole websocket, 服务端向客户端推送消息, websocket主动推送消息
  • 原文地址:https://www.cnblogs.com/yyx1-1/p/6340738.html
Copyright © 2011-2022 走看看