进程信号
概念:信号就是软件中断,信号就是用于向进程通知某个事件的产生,打断进程当前操作,去处理这个事件。
1.操作系统中信号的种类
2.代码演示
Linux中信号的种类: 62种1~31: 非可靠信号(有可能造成事件丢失)
34~64: 可靠信号(不会丢失事件) 信号的生命周期:产生信号->在进程pcb中注册信号->注销账号->处理信号 信号的产生: 硬盘产生:ctrl + c, ctrl + |, ctrl + z; 软件产生:kill命令发送信号给指定进程 kill -signum pid kill命令杀死一个进程的原理:默认给进程发送了终止信号;
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 int main()
5 {
6 while(1){
7 sleep(1);
8 printf("---------\n");
9 }
10 return 0;
11 }
ctrl + z: 发送一个停止信号, 让程序停止运行
进程并没有退出只是停止运行了
程序依然运行在后台;
kill: 给进程发送一个终止信号
进程退出
当使用Ctrl + z, 进程终止之后, 进程就不会再去处理信号了, 所以此时使用kill就不会杀死这个进程.
此时可以使用kill -9, 来杀死这个进程, kill -9 , 就是给进程发送9号命令.
int kill(pid_t pid, int sig);
给pid进程发送sig信号
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<signal.h>
5 int main()
6 {
7 //kill(进程ID, 信号值)
8 kill(getpid(), SIGINT);
9 while(1){
10 printf("-------\n");
11 sleep(1);
12 }
13 return 0;
14 }
程序直接退出;
int raise(int sig);–给进程自身发送一个指定的信号
unsigned int alarm(unsidned int second);–sec秒之后给进程自身发送一个时钟信号–SIGALRM
void abort(void);–给进程自身发送一个SIGABRT信号
3.库函数接口
int sigqueue(pid_t pid, int sig, const union sigval value)
给一个进程发送信号的同时携带一个数据过去
4.信号注册, 注销, 处理
注册: 在进程中注册一个信号让进程知道自己收到了某个信号修改Pending位图,添加一个信号信息节点
注销:将信号信息进程pcb中移除(修改位图,删除节点)
非可靠:删除节点,修改位图为0
可靠:删除信号节点,检查链表中是否还有相同节点,没有则修改位图
处理:信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数
信号的处理方式:
1.默认处理方式
2.忽略处理方式
3.自定义处理方式–用户自己定义信号的处理回调函数
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum:信号值-表示要修改那个信号的处理方式 handler:新的信号处理方式
SIG_DFL-默认; SIG_IGN-忽略; 自定义函数名称
返回值:成功则返回当前信号原来的处理方式,失败则返回SIG_ERR;
5.自定义信号方式的基本使用
演示:
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<signal.h>
5 int main()
6 {
7 //signal(信号, 处理方式)
8 signal(SIGINT, SIG_IGN);
9 //kill(进程ID, 信号值)
10 //kill(getpid(), SIGINT);
11 raise(SIGINT);
12 while(1){
13 printf("-------\n");
14 sleep(1);
15 }
16 return 0;
17 }
此时虽然调用raise但程序并未终止
因为调用signal将SIGINT信号忽略了;
只能使用Ctrl+\退出信号将进程退出
5 void sigcb(int signo)
6 {
7 printf("recv signal:%d\n", signo);
8 }
12 signal(SIGINT, sigcb);
Ctrl+c向进程发送一个2号信号
6.自定义处理方式的信号捕捉流程
7.阻塞
阻塞:信号的阻塞--阻止信号被递达--一个信号被阻塞后,依然收到这个信号会注册,但是暂时不被处理pcb中有pending位图-未决信号结合; 还有阻塞信号集合, 如果要阻塞一个信号,就是在进程的阻塞信号集合中标记这个信号
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:操作类型
SIG_BLOCK–阻塞set集合中的信号 block=block | set
SIG_UNBLOCK–将set集合中的信号解除阻塞block&=~set
SIG_SETMASK–将set集合中的信号设置为阻塞集合的信号block = set
返回值:成功返回0;失败返回-1;