Linux程序设计-进程信号
信号的基本概念
- 信号(signal)机制是Linux系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化。
- 信号是软件中断
- 信号是异步事件
1.不可预见
2.信号有自己的名称和编号
3.信号和异常处理机制 - 信号发生的来源
1.硬件来源:比如我们按下了键盘或者其它硬件故障,信号是由硬件驱动程序产生。
2.软件来源:最常用发送信号的系统函数是kill(), raise(), alarm()和setitimer()等函数,软件来源还包括一些非法运算等操作,软件设置条件(如: gdb调试),信号是由内核产生。
信号与异常处理
信号的处理方法
进程可以通过三种方式来响应和处理一个信号:
- 忽略信号
SIGKILL和SIGSTOP永远不能忽略
忽略硬件异常
进程启动时SIGUSR1和SIGUSR2两个信号被忽略 - 执行默认操作
每个信号有默认动作,大部分信号默认动作是终止进程。 - 捕获信号
告诉内核出现信号时调用自己的处理函数
SIGKILL和SIGSTOP不能被捕获
signal函数
#include <signal.h>
void (*signal(int signo, void(*func)(int)))(int);
//返回:若成功则返回先前的信号处理函数指针,出错则返回SIG_ERR。
//功能:向内核登记信号处理函数
参数
- signo
要登记的信号值 - func
信号处理函数指针
SIG_IGN(忽略信号)
SIG_DFL(采用系统默认的方式处理信号,执行默认操作)。
SIGCHLD信号
- 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用wait调用来等待子进程结束并回收它。
- 避免僵尸进程
信号发送
- 除了内核和超级用户,并不是每个进程都可以向其他的进程发送信号。
- 一般的进程只能向具有相同uid和gid的进程发送信号,或向相同进程组中的其他进程发送信号。
- 常用的发送信号的函数有kill()、raise ()、alarm()、setitimer()、abort()等。
kill和raise函数
#include <signal.h>
int kill(pid_t pid,int signo);
//返回:成功返回o,出错返回-1
//功能:向指定的进程发送某一个信号
int raise(int signo);
//返回:成功返回o,出错返回-1
//功能:向进程本身发送一个信号,相当于kill(getpid(),sig)。
- 参数
pid:接受信号进程的pid
signo:要发送的信号值 - kill函数将信号发送给进程或进程组
0为空信号,常用来检测特定的进程是否存在。
参数pid取值
pid >0 将信号发给进程ID为pid的进程
pid == 0 将信号发给与发送进程同一进程组的所有进程
pid <0 将该信号发送给进程组ID等于pid的绝对值
pid == -1 将该信号发送给发送进程有权限向他们发送信号的系统上
所有进程
定时器
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
//返回:0或以前设置的定时器时间余留秒数
- alarm函数可设置定时器,当定时器超时,产生SIGALRM信号。
- 信号由内核产生,在指定的seconds秒之后,给进程本身发送一个SIGALRM信号。
- 参数为0,取消以前设置的定时器。