沉下心学操作系统(七)进程间通信之信号

文章目录

      • 信号
        • 更改信号的处理方式
          • sigaction()
          • signal()
        • 信号的接收
          • kill()
        • 信号的接收

信号

​ 在unix中,信号是由一个个整数表示,比较常用的信号比如SIGINT,SIGHUP,SIGILL等等,分别是ctrl+c,中断挂起或进程终止,非法指令。

​ 每个信号系统都有自己的默认处理方法,我们可以利用sigaction()函数来更改信号的处理方式。

​ 注意!!信号处理方式是在进程范围内有效,如果一个进程用fork()产生一个子进程,那么在父进程中被忽略的信号在子进程仍然会被忽略(子进程开辟进程空间并将父进程的状态等copy到子进程)

更改信号的处理方式

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

​ 第一个参数代表信号,第二个参数act为新的处理方式,第三个参数oldact是将旧的处理方式存到oldact

signal()
sighandler_t signal(int signum, sighandler_t handler);

​ signal()可以达到和sigaction()同样的目的(相当于sigaction的简化版),第一个参数为信号,第二个参数为收到该信号重写的函数。

​ 由于它在不同的unix系统的实现不同,可能存在移植性问题,不建议使用

信号的接收

kill()
#include 
#include 
int kill(pid_t pid, int sig);

​ 我们可以利用kill来实现发送信号。它的第一个参数为进程号,第二个参数为信号。

​ 当pid > 0,代表给某个指定进程发送;当pid == -1,会给除第一个进程(系统进程,所有用户的祖先)以外所有正在运行的进程发送(在linux下不给自己发);当pid < -1代表给所有进程组等于-pid的发送信号

​ 当sig>0,代表发送指定信号,sig==0不会发送任何信号,但是还会检查是否存在以pid为标识符的进程。常用于检查是否存在该进程(或组)

​ 返回值有成功时为0,错误时-1。有三种错误码:分别代表无效信号、无权发送、进程不存在

信号的接收

​ 信号发出后会被内核检查到,然后内核调用do_signal()执行收到的信号。如果用户定义了某信号的处理方式,那么它可能会在用户空间内处理

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

你可能感兴趣的:(操作系统,进程间通信,面试)