信号的处理:在合适的时机

wKiom1cpvzfCyj30AAJFEcV8TDM202.png

组合键只能发消息给前台

信号处理:默认处理:大部分终止进程,自定义处理:signal,捕捉信号,忽略。

信号本身不重要,针对信号做出响应比较重要。

信号产生:键盘,系统命令:软,硬件:段错误。

信号处理叫抵达,产生到抵达叫未决

信号和进程息息相关,组织信号示意图在PCB:代码,数据,信号

wKiom1cpvuvDNH22AADiRX54a9M163.png

变量先定义,再使用

Makefile的另一种书写方式

bin=my_signal

src=my_signal.c

cc=gcc

$(bin):$(src)

    $(cc) -o  $@ $^

.PHONY:clean

clean:

    rm -f my_signal

信号类函数:

       #include <signal.h>

       int sigemptyset(sigset_t *set);

       int sigfillset(sigset_t *set);

       int sigaddset(sigset_t *set, int signum);(增加一个信号至信号集),sigaddset()用来将参数signum 代表的信号加入至参数set 信号集里。 返回值 执行成功则返回0,如果有错误则返回-1。

       int sigdelset(sigset_t *set, int signum);

       int sigismember(const sigset_t *set, int signum);

int sigprocmask(int how,const sigset_t *set,sigset_t * oldset);

sigprocmask()可以用来改变目前的信号遮罩,其操作依参数how来决定
SIG_BLOCK 新的信号遮罩由目前的信号遮罩和参数set 指定的信号遮罩作联集
SIG_UNBLOCK 将目前的信号遮罩删除掉参数set指定的信号遮罩
SIG_SETMASK 将目前的信号遮罩设成参数set指定的信号遮罩。
如果参数oldset不是NULL指针,那么目前的信号遮罩会由此指针返回。

执行成功则返回0,如果有错误则返回-1。

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
    int count=0;
    while(count<5){
        count++;
        sleep(1);
    }
    //kill(getpid(),11);
    //raise(11);
    abort();
    return 0;
}

//阻塞是种状态,未决是有无
void show(sigset_t* sig)
{
    int i=1;
    for(;i<32;++i)
    {
        if(sigismember(sig,i))
            printf("1");
        else
            printf("0");
    }
    printf("\n");
}
int main()
{
    sigset_t sig_mask;
    sigset_t sig_old;
    sigset_t sig_pending;
    sigemptyset(&sig_mask);
    sigemptyset(&sig_old);
    sigemptyset(&sig_pending);
    sigaddset(&sig_mask,2);
    sigprocmask(SIG_SETMASK,&sig_mask,&sig_old);
    while(1)
    {
        sigpending(&sig_pending);
        show(&sig_pending);
        sleep(1);
    }
    return 0;
}

#include <signal.h>

int sigaction(int signum, const struct sigaction *act,

                     struct sigaction *oldact);

struct sigaction {

               void     (*sa_handler)(int);

               void     (*sa_sigaction)(int, siginfo_t *, void *);

               sigset_t   sa_mask;

               int        sa_flags;

               void     (*sa_restorer)(void);

           };

sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。

unsigned int alarm(unsigned int seconds); 

它的主要功能是设置信号传送闹钟。其主要功能用来设置信号SIGALRM在经过seconds指定的秒数后传送给目前的进程,如果在定时未完成的时间内再次调用了alarm函数,则后一次定时器设置将覆盖前面的设置,当seconds设置为0时,定时器将被取消。它返回上次定时器剩余时间,如果是第一次设置则返回0。

#include<stdio.h>
#include<signal.h>
#include<string.h>
void handler(int sig)
{
    //do nothing
}
int my_sleep(int time)
{
    struct sigaction act;
    act.sa_handler=handler;
    act.sa_flags=0;
    sigemptyset(&act.sa_mask);
    struct sigaction old;
    memset(&old,'\0',sizeof(old));
    sigaction(SIGALRM,&act,&old);//注册信号处理函数
    alarm(time);//time秒后让系统发SIGALRM信号
    pause();//内核切换到别的进程运行
    int ret=alarm(0);
    sigaction(SIGALRM,&old,NULL);//恢复默认信号处理动作
    return ret;
}
int main()
{
    while(1)
    {
        printf("I am sleep...\n");
        my_sleep(5);
    }
    return 0;
}