进程信号
2021/5/20 7:28:12
本文主要是介绍进程信号,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
进程信号
概念:信号就是软件中断,信号就是用于向进程通知某个事件的产生,打断进程当前操作,去处理这个事件。
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;
这篇关于进程信号的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现