Linux 信号(alarm()、pause()等的一个程序示例)

#include <unistd.h>
#include <signal.h>
#include <stdio.h>

void sig_alrm(int signo) {
        NULL;   //nothing to do 
}

unsigned int mysleep(unsigned int nsecs) {  ////gdb单步调试时显示为14,查头文件bits/signum.h为SIGALRM
        struct sigaction newact, oldact;
        unsigned int unslept;
        //在内核注册SIGALRM信号的处理函数sig_alrm
        newact.sa_handler = sig_alrm;
        //初始化sa_mask所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。
        //当某个信号的处理函数被调用时候,当前的信号被加入到进程的信号阻塞集,如果想让其他信号也加入到信号阻塞集合就通过sa_mask来说明。
        sigemptyset(&newact.sa_mask);
        newact.sa_flags = 0;
        //通过传入newact修改了SIGALRM信号的处理动作,传入oldact读取SIGALRM原来的处理动作
        sigaction(SIGALRM, &newact, &oldact); //把SIGALRM对应的编号传入信号处理注册函数(sig_alrm)的参数列表中。
        alarm(nsecs);   //在当前进程设定闹钟,时间一到就终止当前进程
        //调用pause等待,内核切换到别的进程进行了。
        pause();        //将进程挂起,直到有信号抵达

        /*
         *(信号在内核产生,如果阻塞的话也是阻塞在内核,从内核到用户空间的过程中,
         *信号都属于未决信号,进入到用户空间[不执行main的上下文,而是执行信号处理
         *函数的控制流程。]调用sighandler函数时属于信号抵达) 
         *调用了pause,进程就挂起了,nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程
         *然后从内核态准备返回。但在从内核态返回到这个进程的用户态之前要处理未决信号,
         *发现有SIGALRM信号,其处理函数是sig_alrm。这时,切换到用户态执行sig_alrm
         *函数(信号抵达),进入sig_alrm函数时SIGALRM信号被自动屏蔽(当调用信号处理
         *函数时,当前信号被自动加入到当前进程的信号阻塞集)从sig_alrm函数返回时,
         *SIGALRM信号自动杰出屏蔽。然后自动执行系统调用sigreturn再次进入内核,
         *再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数),也就
         *是恢复到main函数的上下文。pause函数返回-1(因为执行了sighandle函数),然后
         *调用alarm(0)取消闹钟,调用sigaction还原SIGALRM信号以前的处理动作.
         */ 
        unslept = alarm(0);
        printf("remain seconds(unslept): %d\n", unslept);
        sigaction(SIGALRM, &oldact, NULL);
        return unslept;
}

int main(void) {
        while(1) {
                mysleep(2);
                printf("two sconds passed\n");
        }
        return 0;
}

 

转载于:https://my.oschina.net/chaenomeles/blog/700025

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值