Linux 进程信号

进程信号

概念:是一种事件通知机制。用于向进程通知某个事件的发生,打断进程当前的操作,去处理这个事件。

Linux中信号的种类:62种

  • 1~31号:非可靠信号/非实时信号,有可能会造成事件丢失。

  • 34~64号:可靠信号/实时信号,不会丢失事件。

    多种信号同时到达,优先处理实时信号。

信号的生命周期

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

信号的产生

硬件产生:ctrl + c:2;ctrl + |:3 ;ctrl + z:20;
软件产生:kill命令发送信号给指定进程 kill -signum pid

产生信号

1.系统调用接口:int kill(pid_t pid, int sig); 给指定进程发送sig信号。
2.库函数:int raise(int sig); 给进程自身发送一个指定的信号。
3.unsigned int alarm(unsigned int seconds); secend秒之后,给进程发送一个时钟信号–SIGALRM。
4.void abort(void); 给进程发送一个SIGABRT信号,使异常的进程终止。

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

int main ()
{
	kill(getpid(), SIGINT);
	while(1)
	{
		printf("-----\n");
		sleep(1);
	}
	return 0;
}

程序并没有死循环打印,是因为收到了SIGINT信号,直接退出。
在这里插入图片描述
在这里插入图片描述
查看函数调用栈,可以看到程序是在kill这里退出。
在这里插入图片描述

注册信号

注册:在进程中注册一个信号,让进程知道自己收到了一个信号。

进程收到信号的实质,就是在一个进程的pcb中,有一个信号pending位图,存放的是未被处理的信号,用来标记是否收到了某个信号。sigqueue,是一个双向链表,表示有多少个信号,及信号的信息。

收到一个信号就会在位图中对应的位置 置1,并在sigquene双向链表中添加一个节点。

非可靠信号:1-31号,如果信号没有被注册,则注册;如果已经被注册,则什么都不做。链表中不会出现相同的非可靠信号信息节点。

可靠信号:34-64号,不管信号是否被注册,都会再注册一遍。链表中可以出现多个重复的可靠信号信息节点。
在这里插入图片描述

注销信号

将信号信息从进程pcb中移除。

非可靠信号:删除节点,修改位图为0。

可靠节点:删除一个信号节点,检查链表中是否还有相同的信号节点,没有则修改位图为0。

处理信号

信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数。

信号的处理方式:

  1. 默认处理方式
  2. 忽略处理方式:什么都不做
  3. 自定义处理方式:用户自己定义信号的处理回调函数。

接口:

sighandler_t signal(int signum, sighandler_t handler);

  • signum:信号值,表示要修改哪个信号的处理方式
  • handler:新的信号处理方式
    SIG_DFL:默认处理方式;
    SIG_IGN:忽略处理方式;
    自定义函数的名称:自定义处理方式;
  • 返回值:成功则返回当前信号原来的处理方式;失败返回SIG_ERR。

信号的阻塞

阻塞:阻止一个信号被递达。一个信号被阻塞后,依旧会受到这个信号,依旧会被注册,但是暂时不处理。

进程pcb中除了有pending位图,存放未被处理的信号,还有一个block阻塞位图,用来标记一个信号被阻塞。
在这里插入图片描述
当pending位图中出现一个信号标记,系统就会去block位图中查看这个信号是否要被处理。

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:操作类型

  • SIG_BLOCK:阻塞set集合中的信号
  • SIG_UNBLOCK:将set集合中的信号解除阻塞
  • SIGSETMASK:将set集合中的信号设置为素色集合的信号

两个比较特殊的信号:

SIGKILL和SIGSTOP信号,这两个信号不可被阻塞,不可被自定义,不可被忽略。就是无法修改处理方式。

信号的基本应用

SIGCHLD信号: 一个子进程退出后,给父进程发送的子进程状态改变信号。但是这个信号的默认处理方式就是什么都不做。

要避免子进程变成僵尸进程,就需要在父进程中调用wait接口阻塞等待,如果不想阻塞等待,就可以用信号来解决,自定义SIGCHLD信号的处理方式,在回调函数中调用waitpid这个接口。

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

函数的重入与不可重入

可重入函数:一个函数,就算重入,也不会出现预期之外的结果。
不可重入函数:一旦函数重入,就有可能出现预期之外的结果。
判断基准点:一个函数内部如果对全局数据进行了不受保护的非原子操作,这个函数就是不可重入函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值