进程间通信之信号

本文深入探讨了UNIX/Linux环境下的信号量机制,详细介绍了信号的使用、异常信号处理、信号集操作函数以及自定义信号捕捉。特别讨论了signal()和sigaction()函数的实现,同时讲解了如何通过信号来管理和回收子进程,以及不同信号的默认动作和处理方式。此外,文章还列举了常见的Linux信号及其用途。
摘要由CSDN通过智能技术生成

关于UNIX环境高级编程和UNIX网络编程的学习记录和总结

信号量signal

信号量是一个计数器,用于多进程对共享数据对象的存取。信号自身不能携带大量信息,所以信号是作为一个标志位来传递信息的,只有在满足条件时才会被发送。
信号早期被称为软中断,一旦信号产生,无论程序执行到什么位置,必须立即停止运行转去处理信号,处理结束,再继续执行后续指令。

注:信号的产生和处理都是有内核完成

产生信号的方式大致有按键产生、系统调用产生 、软件条件产生 、硬件异常产生、使用命令产生
信号的处理方式: 执行默认处理动作、忽略、捕捉。

信号的使用

信号未到达之前称之为未决态,当信号到达时回直接被内核处理掉。多种信号构成一个信号集称,用来表示未到达的信号称为未决信号集,若将信号阻塞,则信号不能递达将一直处于未决态,相当于将之屏蔽,被阻塞的信号集又称为信号屏蔽字(用一个位图来表示)。
查看当前系统中可用信号(kill -l)
在这里插入图片描述
特殊:9号SIGKILL ,19号SIGSTOP 不能被忽略阻塞和捕捉,只能执行默认动作
10号SIGUSR1 ,12号SIGUSR2没有默认事件,但又默认动作为终止进程
17号SIGCHLD默认动作忽略这个信号

信号使用之前,应先确定其 4 要素,而后再用
4要素:编号、名称、对应事件、默认处理动作。
默认动作:
Term:终止进程
Ign: 忽略信号 (默认即时对该种信号忽略操作)
Core:终止进程,生成 Core 文件。 (查验进程死亡原因, 用于 gdb 调试)
Stop:停止(暂停)进程
Cont:继续运行进程

异常信号

除 0 操作 → 8) SIGFPE (浮点数例外) “F” -----float 浮点数。
非法访问内存 → 11) SIGSEGV (段错误)
总线错误 → 7) SIGBUS

使用kill命令来发送终止信号
int kill(pid_t pid, int signum)
​ 参数:
​ pid: > 0:发送信号给指定进程
​ = 0:发送信号给跟调用kill函数的那个进程处于同一进程组的进程。
​ < -1: 取绝对值,发送信号给该绝对值所对应的进程组的所有组员。
​ = -1:发送信号给,有权限发送的所有进程。
​ signum:待发送的信号
​ 返回值:
​ 成功: 0
​ 失败: -1 设置errno

信号集操作函数

sigset_t set;  自定义信号集。

sigemptyset(sigset_t *set); 清空信号集

sigfillset(sigset_t *set); 全部置1

sigaddset(sigset_t *set, int signum); 将一个信号添加到集合中

sigdelset(sigset_t *set, int signum); 将一个信号从集合中移除

sigismember(const sigset_t *set,int signum); 判断一个信号是否在集合中。 在--》1, 不在--》0

设置信号屏蔽字和解除屏蔽:

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

how: SIG_BLOCK: 设置阻塞

	SIG_UNBLOCK: 取消阻塞

	SIG_SETMASK: 用自定义set替换mask。

set: 自定义set

oldset:旧有的 mask。

查看未决信号集:

int sigpending(sigset_t *set);
set: 传出的 未决信号集。

信号操作流程:

  1. sigemptyset(&set)清空信号集;
  2. sigaddset(&set,SIGNUM)添加信号到信号集
  3. sigprocmask(int how, const sigset_t *set, sigset_t *oldset);设置屏蔽字
  4. sigpending(sigset_t *set);查看未决集
  5. 程序执行等待信号

信号捕捉(实现自定义)

signal()实现

typedef void(*sighandler_t)(int);函数指针类型,传入函数名
参数:
signum :待捕捉信号
handler:捕捉信号后的操纵函数
信号捕捉期间:

  • 执行自定义的sa_mask掩码直到捕捉函数执行结束恢复原mask
  • 本信号自动被屏蔽
  • 被屏蔽信号多次发送时,解除屏蔽后只处理一次
void sig_catch(int signo){
   
   printf("catch you %d\n",signo);
   return;
}

signal(SIGINT,sig_catch);//注册捕捉函数

signaction()实现

sa_mask信号屏蔽字,只工作于信号捕捉函数期间,之前的mask工作在整个进程,sa_mask相当于暂时覆盖mask,sa_flag=0(默认屏蔽)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱松子鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值