信号

1.发送信号:kill函数/命令

kill(pid,信号):pid>0 发送给指定进程信号 pid=0发送给本进程组内的其他进程信号

pid=-1 信号发送给处init进程外所有的进程,但是发送者需要拥有对所有目标进程发送信号的权限

Pid<-1信号发送给组id为-pid的进程组中的所有成员

信号的值一般都大于0若信号取值为0 kill不发送任何信号 但是sig=0可以用来检测目标进程或者进程组是否存在,因为检查工作总是在信号发送之前就执行,但是并不可靠。因为进程pid的回绕,可能导致检测的进程不是我们的目标进程,另一方面,该操作并不是原子操作。

kill函数成功返回0 失败返回-1 并设置errno

2.signal函数:两个参数,要捕获的信号类型和信号处理函数的函数指针

  sigaction函数三个参数,更滑健壮的函数接口   要捕获的信号类型,信号处理方式和输出信号先前的处理方式(如果不为NULL的话)

后两个参数都是struct sigaction结构体类型的指针。该结构体中sa_hander指定信号处理函数  sa_mask成员用于设置进程的信号掩码()确切的说是在进程 原有信号掩码的基础上增加信号掩码,以指定哪些信号不能发送给本进程,是一个信号集类型的参数

3.设置进程信号掩码字后,被屏蔽的信号将不能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果取消屏蔽则会立即接收到。

sigpending获取进程当前被挂起的信号集

4.信号是一种异步事件,信号处理函数和程序的主循环是两条不同的执行路线。

但是由于信号处理函数应该是可重入的,不然很容易引发一些竞态条件。也因此信号处理函数中严禁调用不安全的函数

异步的方式代表信号处理函数需要尽可能快的执行完毕,以确保该信号不被屏蔽太久。屏蔽的原因就是因为为了避免之前所说的竞态条件的产生,所以在信号处理期间系统不会再次触发它。

解决这种问题的一种常见方法就是:把信号的主要处理逻辑放在程序的主循环中,当信号处理函数被触发只是建的通知主循环接收信号并传入信号。主循环根据接收到的信号执行相应的逻辑代码

以管道的方式,信号处理函数爱管道的写端写入信号值,主循环则在读端通过IO复用来监听是否有信号可读

 

5.常见信号

SIGPIPE:默认情况下,往一个读端关闭的管道或者socket连接中写入数据将会引发SIGPIPE信号。一般需要在代码中捕获或者处理该信号,或者忽略它,因为程序接收到SIGPIPE信号的默认行为是结束进程,而我们不希望因为错误的写操作而导致进程退出 。

我们可以使用

①send函数的MSG_NOSIGNAL标志来禁止写操作触发SIGPIPE信号。在这种情况下,应该使用send函数反馈的errno值来判断管道或者socket连接的读端是否关闭。

②利用IO复用系统调用检测socket连接的读端是否已经关闭。以poll为例,当管道读端关闭时,写端文件描述符上的POLLHUP事件将被触发;当socket连接被对方关闭时,socket上的POLLRDHUP事件将被触发。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值