zoukankan      html  css  js  c++  java
  • alarm实现sleep

    #include<setjmp.h>
    #include<signal.h>
    #include<unistd.h>
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    static sigjmp_buf env_alrm;
    static volatile sig_atomic_t canjump;
    
    //typedef void (*Sigfunc)(int);
    sighandler_t old_handler = NULL;
    
    static void sig_alrm(int signo){
        if(canjump == 0){
            cout<<"sigsetjmp is not initialized"<<endl;
            return;
        }
        cout<<"sig_alrm starting"<<endl;
        canjump = 0;
        siglongjmp(env_alrm,1);
    }
    
    unsigned int sleep2(unsigned int nesc){
        unsigned int pre_alrm;
        old_handler= signal(SIGALRM,sig_alrm);
        if(old_handler== SIG_ERR)
            return  nesc;
        pre_alrm = alarm(0);
        if(sigsetjmp(env_alrm,1)){
            if(signal(SIGALRM,old_handler) == SIG_ERR){
                cout<<"Restore default func failed"<<endl;
                exit(-1);
             }
             unsigned int tmp = alarm(0);
             if(pre_alrm>nesc){
                cout<<"Restore alarm default,pre_alrm: "<<pre_alrm<<"
     nesc: "<<nesc<<endl;
                return (alarm(pre_alrm-nesc));
             }
             return tmp;
        }
        canjump = 1;  //Initialize OK
        if(pre_alrm)
            alarm(pre_alrm<nesc?pre_alrm:nesc);
        else
            alarm(nesc);
        pause();
    }
    
    static void sig_alrm_main(int signo){
        cout<<"Main alrm starting"<<endl;
    }
    
    int main(int argc, char* argv[]){
        unsigned int unslept;
        if(signal(SIGALRM,sig_alrm_main) == SIG_ERR){
            cout<<"Caught ALRM signal ERR"<<endl;
            exit(-1);
        }
        alarm(10);
        unslept = sleep2(5);
        cout<<"sleep2 returned: "<<unslept<<endl;
        sleep(7);
        exit(0);
    }
    /*
    在UNIX环境高级编程那本书中,使用setjmp及longjmp;但是使用setjmp及longjmp会导致信号只会接收一次,因为进入第一次进入信号处理函数之后,SIGALRM被加入进程 的信号屏蔽字,同时通过longjmp会跳出信号处理程序,此时SIGALRM仍在信号屏蔽字里,导致无法获取到后续的SIGALRM信号。因此使用专门的sigsetjmp */
  • 相关阅读:
    JavaScript之DOM查询
    JavaScript之this解析
    Qt之pro文件解析
    Qt5 调试之详细日志文件输出(qInstallMessageHandler)
    修改 Ubuntu的源为阿里源
    Unable to acquire the dpkg frontend lock
    gcc编译中文字符串后,windows控制台输出乱码
    stm32f103 time2配置,转载
    取反
    单片机,struct ,union定义标志,节约RAM
  • 原文地址:https://www.cnblogs.com/zhang-wen/p/7060286.html
Copyright © 2011-2022 走看看