Linux下的信号

信号

概念:

信号就是一个软件中断;信号就是用于向进程通知某件事情的产生,打断进程当前操作,去处理这件事情。

Linux中信号的种类:

非可靠信号:1–31(有可能会造成事件丢失)
可靠信号:34–64(不会丢失事件)在这里插入图片描述

信号的生命周期:

产生信号—在进程pcb中注册信号—注销信号—处理信号

信号的产生

硬件产生:ctrl+c、ctrl+\、ctrl+z
软件产生:kill命令发送信号给指定进程。kill-signum pid

kill命令杀死一个进程的原理是:默认给进程发送了终止信号

int kill(pid_t pid,int sig);//给pid进程发送sig信号
int raise(int sig);//给进程自身发送一个指定的信号
unsigned int alarm(unsigned int seconds);//sec秒后给进程自身发送一个时钟信号——SIGALRM
void abort(void);//给进程自身发送一个SIGABRT信号
int sigqueue(pid_t pid, int sig,const union sigval value);//给一个进程发送信号的同时携带一个数据过去
信号的注册

在进程中注册一个信号让进程知道自己收到了某个信号。修改pending位图,添加一个信号信息节点。
信号pending位图,用于标记是否收到了某个信号。
sigqueue双向链表:表示有多少个信号。

  • 非可靠信号:如果信号没有注册,则注册;否则什么都不做。链表中不会出现相同非可靠信号信息节点。

  • 可靠信号:不管信号是否注册,都会注册一下。链表中有可能会有多个相同的信号信息节点。

信号的注销

将信号信息进程从pcb中移除(修改位图,删除节点)
非可靠信号:删除节点,修改位图为0;
可靠信号:删除信号节点,检查链表中是否还有相同节点,没有则修改位图。

信号的处理

信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数。
信号的处理方式:
默认处理方式:(大多数信号会直接终止该进程,与信号种类有关)
忽略处理方式:(大多数信号都使用该方法处理)
自定义处理方式——用户自己定义信号的处理回调函数

sighandler_t signal(int signum, sighandler_t handler);

signum:信号值—表示要修改哪个信号的处理方式;
handler:新的信号处理方式
SIG_DFL 默认 //SIG_IGN 忽略
返回值:成功返回当前信号原来的处理方式;失败返回SIG_ERR。
自定义处理方式的信号捕捉流程:程序运行通过系统调用接口、中断及异常从用户态切换到内核态,同时,信号是从程序运行从内核返回用户态之前处理的。
两个特殊的信号:
SIGKILL和SIGSTOP,这两个信号不可被阻塞,不可被自定义,不可被忽略,无法修改处理方式。

信号的阻塞

定义:阻止信号被递达;一个信号被阻塞,依然收到这个信号被注册,但是暂时不处理。
pcb中有pending位图—未决信号集合,还有阻塞信号集合。如果要阻塞一个信号,就是在进程的阻塞信号集合中标记这个信号。

具体操作
int sigprocmask(int how,const sigset_t *set, sigset_t *oldset);

how:操作系统;
SIG_BLOCK:阻塞set集合的信号;block=block/set
SIG_UNBLOCK:将set集合中的信号解除阻塞;block&=~set
SIG_SETMASK:将set集合中的信号设置为阻塞集合的信号。block=set
返回值:成功返回0;失败返回-1.
将所有信号阻塞:sigprocmask block
让程序运行停下来,在这期间给进程发送信号:getchar
解除这些信号的阻塞,查看信号处理:

int sigemptyset(sigset_t *set);//清空set集合
int sigfillset(sigset_t *set);//添加所有信号到set集合中
int sigaddset(sigset_t *set,int signum);//添加signum信号到set集合中
int sigdelset(sigset_t *set,int signum);//聪set集合中移除signum信号
int sigismember(const sigset_t *set,int signum);//判断信号是否在set集合中

信号的基本应用

SIGCHLD信号:

在一个子进程退出后,给父进程发送的子进程状态改变信号,但SIGCHLD信号默认的处理方式是什么都不做。
父进程为了避免僵尸进程需要在wait阻塞等待;如果不想等待,则可以使用信号来解决,自定义SIGCHLD信号的处理方式—在回调函数中调用waitpid接口。
SIGCHDLD是一个非可靠信号——意味着多个子进程同时退出,有可能有丢失事件。

signal (SIGCHLD,SIG_IGN);
SIGPIPE信号:

管道所有读端被关闭,则write触发异常对应的信号。
SIGPIPE信号默认的处理方式就是退出进程,若不想退出则需要自定义忽略。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值