进程间通信--信号1(kill, raise,abort, al
1【信号的概述】
1、信号的概述
信号的概念 信号是 Linux 进程间通信的最古老的方式。信号是软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式 。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。
信号的特点 简单 不能携带大量信息 满足某个特设条件才发送。
一个完整的信号周期包括三个部分:
信号的产生,
信号在进程中的注册,
信号在进程中的注销,
执行信号处理函数
2、信号的编号
1 SIGHUP 用户退出 shell 时,由该 shell 启动的所有进程将收到这个信号 终止进程
2 SIGINT 当用户按下了<Ctrl+C>组合键时用户终端向正在运行中的由该终 终止进程
端启动的程序发出此信号
3 SIGQUIT 用户按下<ctrl+>组合键时产生该信号,用户终端向正在运行中 终止进程
的由该终端启动的程序发出些信号
4 SIGILL CPU 检测到某进程执行了非法指令 终止进程
并产生core 文件
5 SIGTRAP 该信号由断点指令或其他 trap 指令产生 终止进程
并产生core 文件
6 SIGABRT 调用 abort 函数时产生该信号 终止进程
并产生core 文件
7 SIGBUS 非法访问内存地址,包括内存对齐出错 终止进程
并产生core 文件
8 SIGFPE 在发生致命的运算错误时发出。不仅包括浮点运算错误,还 终止进程并产生core
包括溢出及除数为0等所有的算法错误 文件
9 SIGKILL 无条件终止进程。本信号不能被忽略,处理和阻塞 终止进程,可以杀
死任何进程
10 SIGUSE1 用户定义的信号。即程序员可以在程序中定义并使用该信号 终止进程
11 SIGSEGV 指示进程进行了无效内存访问(段错误) 终止进程并产生
core文件
12 SIGUSR2 另外一个用户自定义信号,程序员可以在程序中定义并使 终止进程
用该信号
13 SIGPIPE Broken pipe向一个没有读端的管道写数据 终止进程
14 SIGALRM 定时器超时,超时的时间 由系统调用alarm设置 终止进程
15 SIGTERM 程序结束信号,与SIGKILL不同的是,该信号可以被阻塞 终止进程
和终止。通常用来要示程序正常退出。执行shell命令Kill
时,缺省产生这个信号
16 SIGSTKFLT Linux早期版本出现的信号,现仍保留向后兼容 终止进程
17 SIGCHLD 子进程结束时,父进程会收到这个信号 忽略这个信号
18 SIGCONT 如果进程已停止,则使其继续运行 继续/忽略
19 SIGSTOP 停止进程的执行。信号不能被忽略,处理和阻塞 为终止进程
20 SIGTSTP 停止终端交互进程的运行。按下<ctrl+z>组合键时发出这 暂停进程
个信号
21 SIGTTIN 后台进程读终端控制台 暂停进程
22 SIGTTOU 该信号类似于SIGTTIN,在后台进程要向终端输出数据 暂停进程
时发生
23 SIGURG 套接字上有紧急数据时,向当前正在运行的进程发出些信 忽略该信号
号,报告有紧急数据到达。如网络带外数据到达
24 SIGXCPU 进程执行时间超过了分配给该进程的CPU时间 ,系统产生该 终止进程
信号并发送给该进程
25 SIGXFSZ 超过文件的最大长度设置 终止进程
26 SIGVTALRM 虚拟时钟超时时产生该信号。类似于SIGALRM,但是 终止进程
该信号只计算该进程占用CPU的使用时间
27 SGIPROF 类似于SIGVTALRM,它不公包括该进程占用CPU时间还包 终止进程
括执行系统调用时间
28 SIGWINCH 窗口变化大小时发出 忽略该信号
29 SIGIO 此信号向进程指示发出了一个异步IO事件 忽略该信号
30 SIGPWR 关机 终止进程
31 SIGSYS 无效的系统调用 终止进程并产
生core文件
34~64 SIGRTMIN~SIGRTMAX LINUX的实时信号, 终止进程
它们没有固定的含义
(可以由用户自定义)
可通过man 7 signal查看帮助文档获
发起信号的方式:
a) 当用户按某些终端键时,将产生信号
b) 硬件异常将产生信号。 除数为 0,无效的内存访问等
c) 软件异常将产生信号(定时器)
d) 调用系统函数(如:kill、raise、abort)将发送信号
e) 运行 kill /killall命令将发送信号
2【未决信号集、信号阻塞集】
未决信号集:信号发生 但未被处理的信号集合。(在PCB中)
信号阻塞集:加入信号阻塞集的信号 不被处理。(在PCB中)
3【信号的API】
1、kill函数
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int sig);
功能:
给指定进程发送指定信号(不一定杀死)
参数:
pid : 取值有 4 种情况 :
pid > 0: 将信号传送给进程 ID 为pid的进程。
pid = 0 : 将信号传送给当前进程所在进程组中的所有进程。
pid = -1 : 将信号传送给系统内所有的进程。
pid < -1 : 将信号传给指定进程组的所有进程。这个进程组号等于 pid 的绝对值。
sig : 信号的编号,这里可以填数字编号,也可以填信号的宏定义,可以通过命令 kill -l("l" 为字母)进行相应查看。不推荐直接使用数字,应使用宏名,因为不同操作系统信号编号可能不同,但名称一致。
返回值:
成功:0
失败:-1
2、 raise函数
#include<signal.h>
int raise(int sig);
功能:
给当前进程发送指定信号(自己给自己发),等价于 kill(getpid(), sig)
参数:
sig:信号编号
返回值:
成功:0
失败:非0值
3、abort函数
#include<stdlib.h>
void abort(void);
功能:
给自己发送异常终止信号 6) SIGABRT,并产生core文件,等价于kill(getpid(),SIGABRT);
参数:无
返回值:无
4、alarm函数(闹钟)
#include<unistd.h>
unsigned int alarm(unsigned int seconds);
功能:
设置定时器(闹钟)。在指定seconds后,内核会给当前进程发送14)SIGALRM信号。进 程收到该
信号,默认动作终止。每个进程都有且只有唯一的一个定时器。取消定时器alarm(0),返回旧闹
钟余下秒数。
参数:
seconds:指定的时间,以秒为单位
返回值:返回0或剩余的秒数 定时,与进程状态无关(自然定时法)!就绪、运行、挂起(阻塞、暂停)、
终止、僵尸......无论进程处于何种状态,alarm都计时
5、setitimer函数(定时器)
#include<sys/time.h>
int setitimer(int which,const struct itimerval * new_value, struct itimerval *old_value);
功能:
设置定时器(闹钟)。 可代替alarm函数。精度微秒us,可以实现周期定时。
参数:
which:指定定时方式
a) 自然定时:ITIMER_REAL → 14)SIGALRM计算自然时间
b) 虚拟空间计时(用户空间):ITIMER_VIRTUAL → 26)SIGVTALRM 只计算进程占用cpu的时间
c) 运行时计时(用户 + 内核):ITIMER_PROF → 27)SIGPROF计算占用cpu及执行系统调用的时间
new_value:struct itimerval, 负责设定timeout时间
struct itimerval {
struct timerval it_interval; // 闹钟触发周期
struct timerval it_value; // 闹钟触发时间
};
struct timeval {
long tv_sec; // 秒
long tv_usec; // 微秒
}
itimerval.it_value: 设定第一次执行function所延迟的秒数
itimerval.it_interval: 设定以后每几秒执行function
old_value: 存放旧的timeout值,一般指定为NULL
返回值:
成功:0
失败:-1