系列文章目录
目录
2.1 绝大部分信号:默认动作都是终止程序,比如下面四个信号
前言
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
一 信号
linux通过信号去控制进程的行为动作(程序的退出,程序的暂停,程序的继续),Linux通过以下命令可以查看信号的情况。
(1) 1--31号信号:非实时信号, 能嵌套
signal(SIGINT,fun)
void fun(int num)
{
signal(SIGQUIT,otherfun);
}
(2) 34--64号信号(新增):实时信号,不能嵌套
1 信号总共有四种响应方式:
- 信号的默认响应动作(就是linux系统已经规定好的)
- 改变信号的响应动作
- 信号的忽略
- 信号的阻塞(信号的屏蔽)
2 信号的默认响应动作
2.1 绝大部分信号:默认动作都是终止程序,比如下面四个信号
SIGINT ---》ctrl+c 就是给当前进程发送了SIGINT信号
SIGSTOP ---》程序暂停
SIGCONT ---》程序继续
SIGKILL ---》杀死进程
2.2 发送信号的常用命令:
kill -信号的序号 进程的ID
kill -信号的名字 进程的ID
kill -9 hello
kill -SIGKILL hello
kill -KILL hello
killall -信号的序号 进程的名字
killall -信号的名字 进程的名字
killall -9 hello
killall -SIGKILL hello
killall -KILL hello
3 相关的接口函数
3.1 信号的发送 kill()
#include <signal.h>
int kill(pid_t pid, int sig);
参数:pid --》进程的ID号
sig --》信号的序号
3.2 捕捉信号并改变信号的响应动作(重点)
// 给 void (*)(int)类型的函数指针换了名字,名字叫做 sighandler_t
typedef void (*sighandler_t)(int);
参数:表示捕捉到的信号的序号//实际应用:保护你的代码不受干扰,可以收到信号以后按照程序员的逻辑去执行新的代码
sighandler_t signal(int signum, sighandler_t handler);
返回值:成功 返回函数指针
失败 NULL
参数:signum --》你要捕捉的信号的序号
handler --》函数指针signal函数总共有三个功能
功能一:改变信号的响应动作
功能二:SIG_IGN 忽略信号,信号发送给进程,进程直接舍弃,左耳进右耳出
功能三:SIG_DFL 按照信号默认的动作响应注意:SIGKILL和SIGSTOP这两个信号既不能改变它们的响应动作,也不能忽略,其他的信号可以
3.3 raise()和alarm()
int raise(int sig); //自己给自己发信号
raise(9); // 等价于kill(getpid(),信号的序号)
unsigned int alarm(unsigned int seconds); //定时器
参数:seconds --》单位是秒
比如: alarm(5); //间隔5秒钟给当前进程发送SIGALRM信号
3.4 阻塞进程,等待信号的到来
int pause(void); //信号不来 ,一直阻塞
3.5 信号的发送和捕捉函数
linux中有两组常用的信号发送和捕捉函数
- kill和signal
- sigqueue和sigaction (升级版)
//给进程发送信号,同时携带额外
int sigqueue(pid_t pid, int sig, const union sigval value) 数据
参数:union sigval {
int sival_int; //你要发送给进程的数据
void *sival_ptr; //你要发送给进程的一个首地址
};
//捕捉信号,改变信号的响应动作int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
参数:(重点)struct sigaction {
void (*sa_handler)(int); // 函数指针 1
void (*sa_sigaction)(int, siginfo_t *, void *); // 函数指针 2
sigset_t sa_mask; //存放你要阻塞的信号
int sa_flags; // 开关:设置SA_SIGINFO 选择函数指针 2,设置0选函数指针 1响应
void (*sa_restorer)(void); //保留字段,没有什么用
};
act --》保存你设置的信号响应函数
oldact --》(做备份的)保存当前进程原本设置的信号响应函数void (*sa_sigaction)(int, siginfo_t *, void *); //函数指针 2
参数:int --》你捕捉的信号的序号
siginfo_t --》结构体指针,用来存放sigqueue发送过来的额外数据
{
int si_int; //保存发送过来额外数据
void *si_ptr; //保存发送过来的指针
}
总结
本文主要讲解了进程间信号通信的原理和相关的接口函数。