当前位置: 首页 > news >正文

Linux探秘坊-------14.信号

1.预备知识

在这里插入图片描述
在这里插入图片描述

2.信号的产生

例如如果我们想要把一个进程给终止掉,那么我们就可以使用ctrl+c来终止进程,ctrl+c就是一个信号

在这里插入图片描述
如何更改处理型号的方式呢?

void handlerSig(int sig)//重新修改处理信号的方式
{std::cout << "获得了一个信号: " << sig << std::endl;
}//函数调用
signal(2, handlerSig);//2就是ctrl+c对应的信号,handlersig是函数指针

3.进程分类

在这里插入图片描述

4.信号创建方式--------系统调用----以kill函数为例

ctrl+c是直接从键盘上输入的信号,我们也可以自己写一个系统调用–mykill来实现一样的效果

mykill.cc:

#include <iostream>
#include <string>
#include <sys/types.h>
#include <signal.h>// ./mykill signumber pid
int main(int argc, char *argv[])//编译完成后,bash进程运行指令./mykill 9 1234
{if(argc != 3)//表示指令个数,:1../mykill 2.9 3.1234--进程pid{std::cout << "./mykill signumber pid" << std::endl;return 1;}int signum = std::stoi(argv[1]);//argv【1】存储指令:9 pid_t target = std::stoi(argv[2]);//argv【2】存储指令: 1234--进程pid
//二者都要使用stoi函数转换成征整形!!!!!int n = kill(target, signum);//调用kill函数,参数是进程pid和信号if(n == 0){std::cout << "send " << signum << " to " << target << " success.";}return 0;
}

testSig.cc:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>void handlerSig(int sig)
{std::cout << "获得了一个信号: " << sig << std::endl;exit(13);//在编译完运行程序后只要通过键盘输入信号,那么都改成输出,特别注意---⑨是没有办法改的,因为9号是强制杀掉进程,为了避免垃圾程序一直处于运行中,需要保留9号来及时删除程序,绝大部分的信号的原始处理方式都是终止进程
}int main()
{for(int i = 1; i < 32; i++)signal(i, handlerSig);//改写31个普通信号处理机制,这个循环只有在用户输出信号时才运行,无论用户输入什么信号,都会把其改写成输出信号编号,而不使用信号原本的功能int cnt = 0;while (true){std::cout << "hello world, " << cnt++ << " ,pid: " << getpid() << std::endl;sleep(1);}
}

makefile:

.PHONY:all
all:testsig mykilltestsig:testSig.ccg++ -o $@ $^ -std=c++11
mykill:mykill.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f testsig mykill

信号异常现象:

  • 除0
#include <stdio.h>#include <signal.h>
void handler(int sig)
{printf("catch a sig : %d\n", sig);
}
// v1
int main()
{//signal(SIGFPE, handler); // 会跳8号错误:::8) SIGFPEsleep(1);int a = 10;a/=0;while(1);return 0;
}
  • 野指针:
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{printf("catch a sig : %d\n", sig);
}
int main()
{//signal(SIGSEGV, handler);sleep(1);int *p = NULL;  // p被初始化为空指针(不指向任何有效内存)
*p = 100;       // 试图通过空指针写入数据while(1);return 0;
}

使用系统调用alarm:

#include <iostream>
#include <unistd.h>
#include <signal.h>
int main()
{int count = 0;alarm(1);//运行一秒后给信号,直接终止进程while(true){std::cout << "count : " 
<< count << std::endl;count++;}return 0;
}

运行结果:

  • … …
    count : 107148
    count : 107149
    Alarm clock

5.信号保存

在进程的pcb表中存有如下内容:

在这里插入图片描述

  • 其中handler的第一个表示default----即保持指令原来的功能
  • 第二个表示ignore------即忽略这个指令的功能

在这里插入图片描述

运行结果就是:

在这里插入图片描述

  • 就算我输出了ctrl+c,但是进程依旧没有停止 因为2号信号被忽略了!!!!

部分函数使用:
在这里插入图片描述

1.sigprocmask函数---------把信号对应的block表进行修改

在这里插入图片描述

2.sigpending函数---------把信号对应的pending表打印出来

在这里插入图片描述

  • 因为是以位图的形式打印出来的,所以返回值是int类型

6.信号处理

1.信号捕捉

在这里插入图片描述

http://www.lryc.cn/news/589439.html

相关文章:

  • ObservableValidator自定义错误样式
  • 从知识变现到创始人IP:知识付费的进阶之路
  • zip 加密压缩文件的原理是什么?
  • 【Java】【企业级应用】学生信息管理系统项目介绍
  • 算法入门:BFS与DFS详解(C++实现)
  • 【kubernetes】--ConfigMap
  • 极致cms多语言建站|设置主站默认语言与设置后台固定语言为中文
  • frp内网穿透(二)
  • 牛客:HJ20 密码验证合格程序[华为机考][字符串]
  • 一般芯片电气特性中Flash参数达到其最大值的条件是什么?
  • 【人工智能99问】激活函数有哪些,如何选择使用哪个激活函数?(5/99)
  • 全新 Python 项目托管到 Gitee 私有仓库完整流程(带详细命令注释)
  • 【PTA数据结构 | C语言版】构造二叉树
  • 软件质量概述
  • 使用 pdb 来 debug 调试 python 程序
  • I3C通信驱动开发注意事项
  • Linux715 磁盘管理:逻辑卷
  • golang二级缓存示例
  • 随机奖励能提升Qwen数学表现?本质是数据污染
  • NuGet01-安装及使用
  • Linux下编译海思WS63 SDK全攻略
  • 关于Linux下Cursor的使用
  • 如何设计实现开发自助重启工具-01-设计篇
  • 代码随想录八股文训练营总结
  • lesson14:Python的推导式
  • 2025-07-15 李沐深度学习6——Softmax回归
  • 项目:简单学生成绩管理系统设计
  • Nginx配置反向代理
  • 深入解析:磁盘级文件与内存级(被打开)文件的本质区别与联系
  • 脚手架新建Vue2/Vue3项目时,项目文件内容的区别