Linux信号

信号的概念

    信号是软件层上对中断的一种模拟,又称为软件中断(软中断)。

 

信号和中断的相同和区别

    信号和中断都是异步通信方式。

    信号没有优先级,中断有优先级;信号处理程序是在用户态(软件层),中断处理是在内核态;信号处理有延迟,中断处理及时。(由于信号处理是在软件层面上实现的,其实现手段导致信号有很长的延迟性,但对用户来说不易察觉)

 

内核对信号的处理

    可以告诉内核在信号出现时按以下3种方式之一进行处理:

    (1)忽略信号(SIGKILL和SIGSTOP不能被忽略,因为这两个信号是 内核 和 root 用来管理进程的)

    (2)捕捉信号(SIGKILL和SIGSTOP不能被捕捉)

    (3)默认处理(执行系统默认动作,man 7 signal可以查看)

 

查看信号

    kill -l查看所有信号。

    1-31是Unix继承过来的,是不可靠信号,非实时信号,不支持排队,可能会造成信号丢失。

    34-64是优化后的,可靠信号,实时信号,支持排队,不会丢失信号。

 

信号的产生

(1)按键产生

    ctrl+c    2) SIGINT

    ctrl+z    20)SIGTSTP(停止/暂停)

    ctrl+\     3)SIGQUIT(退出) 

(2)硬件异常产生

    除0操作        8)SIGFPE

    非法访问内存     11)SIGSEGV(段错误)

    总线错误       7)SIGBUS

(3)函数产生

    int kill(pid_t pid, int sig);

    int raise(int signal);

    void abort(void);

    unsigned int alarm(unsigned int seconds);

    setitimer

 

信号的控制

这里写图片描述

task_struct结构体解析

一个block/pending/handler占8字节,一共64bit,每个信号占一位。可以通过设置block来对信号进行屏蔽。

block信号阻塞,例如sigint为1时,阻塞sigint信号,可以通过信号集操作函数进行操作,如果是实时信号(可靠信号),则被阻塞的信号会排队(直到达到队列上线,多余的信号丢掉),如果是非实时信号(不可靠信号)则只会保留一个信号,等恢复不阻塞状态时,继续发送信号,实时信号会受到多个信号,而非实时信号只有一个。

pending信号未决,例如sigint为1表示收到sigint信号但是没有送达。block设置为1时有发送信号则pending变为1。不能设置,只读。当pangding为1时表示有信号被阻塞了,当恢复不阻塞时,继续传送信号。

handler信号处理方式,默认处理方式或者自己捕捉信号处理。

 

信号集操作函数

 
 ①、int sigemptyset(sigset_t *set); 
    作用:将某个block集(信号集)清0 
 ②、 int sigfillset(sigset_t *set); 
   作用:将某位信号集置1 
 ③、int sigaddset(sigset_t *set, int signum); 
   作用:将某个信号加入信号集 

 ④、 int sigdelset(sigset_t *set, int signum); 
   作用: 将某个信号清出信号集

    ⑤、int sigismember(const sigset_t *set, int signum); 
    作用:判断某个信号是否在信号集中 

    上面五个函数用于处理sigset_t类型的信号集,当规划好信号集后,需要用sigprocmask函数将信号集应用到pcb(Processing Control Block)中。具体如下:

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

    关于how选项:

    (1)SIG_BLOCK        将set中的信号加入阻塞(block),与block进行或操作

    (2)SIG_UNBLOCK   将set中的信号移出阻塞,block设为0

    (3)SIG_SETMASK    将block设为set

    如果how被忽略,而oldset不为空,则将block的值返回到oldset中。


未决信号集

    sigpending函数

 

信号捕捉函数

    signal函数

    typedef void (*sighandler_t)(int);

    sighandler_t signal(int signum, sighandler_t handler);

     signal函数有两个函数,一个是int类型的signal,一个是sighandler_t类型的函数指针。返回值也是sighandler_t类型。

    sighandler_t的一个参数int,传入的signal。

 

    sigaction函数

    int sigaction(int signum, const struct sigaction *act, struct sigaction* oldact);

    可以在struct sigaction里传送数据

    struct sigaction{

        void (*sa_handler)(int);

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

        sigset_t sa_mask;

        int sa_flags;

        void (*sa_restorer)(void);

    };

参考博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值