当前位置: 首页 > 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.xdnf.cn/news/1127305.html

相关文章:

  • Axios 完整功能介绍和完整示例演示
  • OSPFv3中LSA参数
  • 【Luogu】每日一题——Day3. P6392 中意 (数学 取模)
  • 【深度学习优化算法】06:动量法
  • Sentinel热点参数限流完整示例实现
  • 高温车间(60℃+)如何选高温/宽温边缘网关设备?
  • 如何把手机ip地址切换到外省
  • Datawhale 25年7月组队学习coze-ai-assistant Task1学习笔记:动手实践第一个AI Agent—英伦生活口语陪练精灵
  • 学习C++、QT---26(QT中实现记事本项目实现文件路径的提示、现在我们来学习一下C++类模板、记事本的行高亮的操作的讲解)
  • etcd自动压缩清理
  • QT——QComboBox组合框控件
  • Flink实战项目——城市交通实时监控平台
  • 函数柯里化详解
  • Luban配置教程
  • 如何在simulink中怎么获取足端轨迹代码解释?
  • 【卡尔曼滤波第六期】集合变换卡尔曼滤波 ETKF
  • PyTorch笔记7----------计算机视觉基础
  • SSM框架学习DI入门——day2
  • flutter弹窗:fluttertoast
  • AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
  • 开通保存图片权限
  • 专业文档搜索工具,快速定位文本内容
  • 简单2步配置CadenceSkill开发编辑器,支持关键字高亮
  • 《大数据技术原理与应用》实验报告四 MapReduce初级编程实践
  • excel 通过openpyxl表格下载和插入图片
  • Linux的用户和用户组与权限解析、环境变量说明与配置、sudo配置解析和使用
  • Linux系统下 挂载exfat文件系统U盘
  • 【C语言进阶】字符函数和字符串函数的内部原理
  • 解锁Redis:从安装到配置的全攻略
  • sqli-labs靶场通关笔记:第18-19关 HTTP头部注入