一、基本概念
1、中断:
在程序执行过程中,插入了另一段程序的执行过程。该段程序执行结束后回到中断点继续执行原来的程序。
2、同步通信与异步通信:
同步通信:发送方发送数据,接收方接收数据,双方在很短的时间内完成数据的交换,否则会造成一方的阻塞。所以
同步通信是一种阻塞模式的通信。
异步通信:通信中接收方并不知道数据什么时候会到达,当前进程一直准备接收数据,同时也在做自己的事情,一旦
数据到达立即接收处理。
3、信号是一种异步通信方式,信号是在软件层次上对中断机制的一种模拟。同时,信号是进程间通信机制中唯一
的异步通信机制。
在Linux系统下可以通过:“kill -l”命令来查看系统的64中信号,每种信号都有自己的宏定义,常见的几种
信号有如下几种:
信号名 | 定义 | 默认操作 |
---|---|---|
SIGINT | 该信号中用户输入INTR字符(CTRL + C )时发出,终端驱动程序发送此信号并送到前台进程的每一个进程 | 终止进程 |
SIGKILL | 该信号用来立即结束程序的运行,并且不能被阻塞和忽略 | 终止进程 |
SIGALARM | 当一个定时器到时的时候发出该信号 | 终止进程 |
SIGSTOP | 该信号用于暂停一个进程,且不能被阻塞、忽略或处理 | 暂停进程 |
SIGTSTP | 该信号用于交互停止进程,用户输入SUSP字符(通常是CTRL + Z)时发出该信号 | 停止进程 |
SIGCHLD | 子进程状态发生改变时,父进程会受到这个信号 | 忽略 |
二、Linux下信号的处理方式
在Linux系统下当进程收到一个信号后,它有三种方式对信号进行相应。
1、忽略信号:
即对信号不做任何处理,其中有两个信号不能进行忽略:SIGKILL及SIGSTOP。对信号进行忽略处理需要调用
signal或者sigaction函数,对指定信号进行SID_IGN设置,表示忽略指定的信号。
以这种方式对信号进行忽略处理即告知操作系统,当进程接收到指定的信号时操作系统不用告知我,操作系统
直接处理就好,进程本身不关心这种信号。
2、捕捉信号:
定义相应的信号处理函数,如果某种信号发生,执行指定操作。信号的处理函数和信号的捕捉需要通过signal
函数进行关联,即当捕捉到某种信号后去执行相应的信号处理函数。
3、执行默认操作:
当某种信号发生时,操作系统已默认缺省的方式进行处理。
三、信号的发送与设置
1、定时器信号
1、alarm函数:
函数原型:unsigned int alarm(unsigned int seconds);
函数参数:seconds 指定秒数,系统经过seconds秒后向该进程发送SIGALRM信号。如果seconds == 0,
表示取消当前的定时器。
返回值:>=0 如果调用此alarm之前,进程中已经设置了闹钟时间,则返回上一个闹钟剩余的时间;否则,返回0
=-1 出错。
说明:alarm也称为闹钟函数,它可以在进程中设置一个定时器。当定时器指定的时间到了之后,它就向进程发送
一个SIGALRM信号。需要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm函数之前已经设置过闹
钟时间,则任何以前的闹钟时间都会被代替。
2、pause函数
函数原型:int pause(void);
函数功能:它用于把一个进程挂起,直到接收到信号为止。
返回值:-1,并且把errno设置为EINTR。
2、信号的处理、设置
1、signal函数:
函数原型:typedef void (*sighandler_t)(int);//函数指针
sighandler_t signal(int signum, sighandler_t handler);
函数参数:signum 指定信号对应的代码数字或者宏定义。
handler SIG_IGN,忽略该信号
SIG_DFL,采用系统默认方式处理信号
自定义的信号处理函数
说明:
1、signal函数并不是发送信号,只是将信号与相关的信号处理函数进行关联。
2、信号通信是异步通信,只要在当前进程没有接收到信号并进行默认处理之前,都可以调用signale函数来对信号
进行捕捉处理。
3、信号的发送
1、kill函数:
函数原型:int kill(pid_t pid, int sig);
函数参数:pid >0,发送信号给进程号为pid的进程
==0,信号被发送给所有和当前进程在同一进程组的每一个进程。
<-1,信号发送给进程组好为-pid的每一个进程
sig 信号的类型,Linux下64中信号类型都有其对应的宏定义。
返回值:成功,返回0;失败,返回-1。
说明:kill函数和kill命令一样,可以发送信号给进程或进程组。需要注意的是,它不仅可以终止进程(SIGTERM),
还可以向进程发送其它信号。
kill命令:kill -signal pid; <==> killall -signal 可执行程序
signal表示相应的信号对应的数字,或则是宏定义。
2、raise函数:
函数原型:int raise(int sig);
函数参数:sig 信号类型
返回值:成功,返回0;失败,返回-1。
说明:raise函数也可以用来发送信号,但是它与kill函数的区别在于:raise函数只允许向自身进程发送信号。