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

网站底部制作免费个人网站建设公司

网站底部制作,免费个人网站建设公司,泉州高端网站建设,长春网站建设phpjz1.前言 我们会讲解五种信号产生的方式: 通过终端按键产生信号#xff0c;比如键盘上的CtrlC。kill命令。本质上是调用kill()调用函数接口产生信号硬件异常产生信号软件条件产生信号 前两种在前一篇文章中做了介绍#xff0c;本文介绍下面三种. 2. 调用函数产生信号 2.1 k…1.前言 我们会讲解五种信号产生的方式: 通过终端按键产生信号比如键盘上的CtrlC。kill命令。本质上是调用kill()调用函数接口产生信号硬件异常产生信号软件条件产生信号 前两种在前一篇文章中做了介绍本文介绍下面三种. 2. 调用函数产生信号 2.1 kill() sig是信号编码pid是捕获信号的进程pid。 我们编写一个程序proc.c #include stdio.h #include unistd.hint main() {while(1){printf(I am a process, pid: %d\n, getpid());sleep(1);} }利用mykill中的kill()杀掉它 #include iostream #include unistd.h #include signal.h #include sys/types.h using namespace std; //argv*[]:mykill pid signal int main(int argc, char const *argv[]) {if(argc ! 3){cout usage: ./mykill signal pid endl;//告诉用户用法exit(1);}int signo atoi(argv[1]);int pid atoi(argv[2]);int ret kill(pid, signo);if(ret -1){perror(kill);exit(2);}//kill函数返回值成功返回0失败返回-1return 0; }2.2 raise() raise(sig)是对kill(getpid(),sig)的封装。 2.3 abort() 我们编写代码来测试一下abort函数 #include iostream #include cstdlib #include unistd.h #include signal.h #include sys/types.h using namespace std;void myhandler(int signo) {cout process get a signal: signo endl;// exit(1); } int main(int argc, char *argv[]) { int cnt 0;while (true){cout I am a process, pid: getpid() endl;sleep(1);cnt;if(cnt % 2 0) {abort();}} }重新编译并运行 我们怎么确定abort()调用的是6号信号呢我们可以捕捉6号信号修改代码为 //头文件等略 void myhandler(int signo) {cout process get a signal: signo endl; } int main(int argc, char *argv[]) { signal(SIGABRT, myhandler);int cnt 0;while (true){cout I am a process, pid: getpid() endl;sleep(1);cnt;if(cnt % 2 0) {abort();}} }SIGABRT确实被捕获到了可为什么最后还是调用了abort()呢不是应该一直循环下去吗 我们将abort()注释掉换成“kill(getpid(), 6);” 重新编译运行 发现程序没有推掉说明abort()虽然是对SIGABORT的封装但后面还增加了自己的细节致使所在进程退出而SIGABORT不会终止进程它表示程序出现异常。 3. 硬件异常产生信号 3.1 “除0代码” 我们编写一段“除0代码” #include iostream #include unistd.husing namespace std;int main() { cout div before endl;sleep(5);int a 10;a / 0;//异常cout div after endl;sleep(1);return 0; }编译运行 输入指令“man 7 signal”,查阅信号对应的注释 找到注释对应的信号SIGFPE, 是8号信号中断了该进程。我们尝试捕获*号信号 #include iostream #include unistd.h #include signal.husing namespace std;void handler(int signo) {sleep(1);cout catch signal signo endl; } int main() { signal(SIGFPE,handler);cout div before endl;sleep(5);int a 10;a / 0;//异常cout div after endl;sleep(1);return 0; }重新编译运行并监视 我们发现当SIGFPE被捕获后进程不会退出并且一直执行“自定义行为”也就是一直打印。 3.2 “野指针代码” 我们编写一段“野指针代码” #include iostream #include unistd.h #include signal.h using namespace std; int main() { cout point error before endl;sleep(3);int *p nullptr;*p 10;cout point error after endl;sleep(1);return 0; }段错误是11号信号也就是内存错误 我们捕捉该信号 #include iostream #include unistd.h #include signal.h using namespace std; void handler(int signo) {cout catch signal: signo endl;sleep(1); } int main() { signal(SIGSEGV,handler);cout point error before endl;sleep(3);int *p nullptr;*p 10;cout point error after endl;sleep(1);return 0; }同样11号信号被捕捉后段错误异常就不会终止进程。 所以程序出现异常进程不一定会被终止当然这是因为我们自定义了进程接收到信号后的处理行为。所以一般情况下进程出现异常了都会终止。 3.3 为什么“除0、野指针”会让进程终止呢 这是因为操作系统遇到“除0、野指针”问题会发送信号给进程进程处理信号会终止自己。这也说明不论产生信号的方式是什么最终都是由操作系统发送信号给进程。 但这不是关键关键是操作系统怎么知道代码中的“除0、野指针”问题 对于除0错误:当CPU从上到下执行程序的代码时如果遇到了除0CPU中的状态寄存器的溢出标志位就会由0变为1操作系统就知道CPU当前调度的进程出现了异常操作系统是硬件的管理者。注意寄存器信息是进程的上下文进程之间是独立的所以上个进程的溢出标识符为1并不会影响到下一个进程更不会让操作系统出错。 总结除0问题会被转换成硬件问题表现在硬件上从而被操纵系统识别到操作系统就会处理该问题该问题并不会影响到操作系统的稳定性只会影响到当前进程异常的进程。 那么我们捕获信号后为什么程序会一直打印而不崩溃呢 这是因为问题一直没有被修复当进程被调度进CPU,状态寄存器出错操作系统向当前进程发送信号进程执行信号打印打印完后上下文中的错误又没被修复进程还一直在调度运行中状态寄存器一直”出错“操作系统一直发送信号所以程序一直打印。 那么捕捉信号不修正问题为什么还要有“自定义信号处理”的方法呢 自定义信号捕捉是为了让用户知道程序为什么崩溃便于打印日志以及保存崩溃前的信息。而不是为了让用户直接解决当前的进程异常问题。 对于“野指针”问题是因为虚拟地址无法经过页表转换为物理内存地址可能溢出或者没有访问权限,而页表是由MMU维护的MMU会发送对应的信号被操作系统识别。 4.软件条件产生异常 处理硬件可能产生异常软件也可能产生异常。比如我们在匿名管道一章讲解的管道四大特征之一当管道的写端被关闭后读端的进程会自动退出。这是13号信号SIGPIPE造成的。 软件运行中可能会出现一些特殊事项致使软件的一些条件没有被满足就可能产生异常。 我们拿alarm()举例 4.1 alarm alarm() 函数是 Unix 和类 Unix 系统编程中的一个标准函数它用于设置一个定时器当定时器到达指定时间后会向进程发送一个 SIGALRM 信号。这个函数通常用于实现定时任务或超时处理。 函数原型 #include unistd.h unsigned int alarm(unsigned int seconds);参数 seconds定时器的秒数。如果设置为 0则会关闭之前设置的定时器。 返回值 返回值是之前定时器剩余的时间秒也就是前一个闹钟要响起的剩余时间防止多个闹钟在同一时间响起。如果之前没有设置定时器则返回 0。 使用示例 以下是一个简单的 C 程序示例演示如何使用 alarm() 函数 #include iostream #include unistd.h using namespace std;int main() { int n alarm(5);//设置一个5秒的闹钟while(1){cout the proc is running endl;sleep(1);}return 0; }我们在查一下信号表 这样我们还不确信可以捕获该信号测试一下 #include iostream #include unistd.h #include signal.h using namespace std; void handler(int signo) {cout catch a signal,the number: signo endl;sleep(1); } int main() { int n alarm(5);//设置一个5秒的闹钟signal(SIGALRM,handler);while(1){cout the proc is running endl;sleep(1);}}这个闹钟为什么只响一次呢我们之前的“野指针”和“除0”都不断的打印自定义行为这个却打印一次因为闹钟不是异常。 如果我们要让闹钟每隔5秒打印一次可以在handler()修改为 void handler(int signo) {cout catch a signal,the number: signo endl;alarm(5); }我们利用这个原理可以让进程每隔一段时间执行特定的工作比如打印日志。 void work() {cout print log... endl; } void handler(int signo) {work();cout catch a signal,the number: signo endl;alarm(5); }注意事项 alarm() 只能设置以秒为单位的定时器如果需要更精确的时间控制可以考虑使用 setitimer() 或 timer_create() 等函数。alarm() 设置的定时器是单次的如果需要重复触发需要在信号处理函数中再次调用 alarm()。在多线程程序中使用 alarm() 时要特别小心因为它是针对整个进程的可能会影响其他线程的行为。 5. Core dump SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump,Core Dump是什么意思呢 我们在进程等待中也提到过Core Dump, 我们编写一段父进程回收子进程的代码分别用8号信号和2号信号终止子进程获取子进程的core dump标志 2号信号和8号信号杀死进程的core dump标志确实不一样那么这个表示到底是什么意思呢 由于云服务器一般把core file文件的大小设为0相当于关闭了core dump的功能或者操作系统重新配置了core文件生成的目录所以我们用ll查看当前目录不会看到相关文件我们可以用ulimit -a查看系统资源的限制信息其中就包括core文件的大小然后用“ulimit -c 10240,将core file 的大小设置为10240K, 然后重新运行程序再用8号信号杀死此时如果还看不到相关的core文件可在命令行输入“sudo bash -c echo core.%p /proc/sys/kernel/core_pattern”,core文件不存在的原因 重新编译再杀死进程就有对应的core文件了。 所以一旦打开了系统的core dump功能某个进程因异常而被Action为core的信号终止时操作系统就会将进程在内存中的运行信息dump(转储)到进程的工作目录下磁盘中形成core.pid文件。 那么core.pid文件有什么用呢 该文件保存了程序中断的原因可以帮助我们更好的识别、修改bug。 为什么core dump默认是关闭的呢 在 Linux 系统中core dump 默认是关闭的主要原因有以下几点 磁盘空间占用core dump 文件会包含程序在崩溃时的内存映像包括代码段、数据段、堆、栈等信息其大小可能非常大尤其是对于大型应用程序。如果系统中多个程序频繁崩溃并生成 core dump 文件会占用大量的磁盘空间影响系统的正常运行和存储资源的使用效率。性能影响生成 core dump 文件需要将大量内存数据写入磁盘这个过程可能会消耗较多的 I/O 资源导致系统性能下降。对于一些对性能要求较高的系统或应用程序这种性能损失是不可接受的。安全性考虑core dump 文件可能包含程序运行时的敏感信息如用户数据、加密密钥、系统配置等。如果这些文件被未授权的用户访问可能会导致信息泄露带来安全隐患。因此默认关闭 core dump 功能可以在一定程度上保护系统的安全性。管理复杂性如果系统中所有程序都默认开启 core dump 功能可能会导致生成大量的 core dump 文件增加了系统管理员管理和分析这些文件的复杂性。管理员需要定期清理这些文件以避免磁盘空间被占用同时还需要对每个文件进行分析以确定程序崩溃的原因这会消耗大量的时间和精力。 当然core dump 文件对于程序开发和故障排查是非常有用的它可以帮助开发者快速定位程序崩溃的原因提高程序的稳定性和可靠性。因此在需要调试程序或分析程序崩溃原因时可以手动启用 core dump 功能并根据实际情况设置合适的文件大小限制和保存路径。 来源https://kimi.moonshot.cn/chat/
http://www.tj-hxxt.cn/news/232350.html

相关文章:

  • 怎样建网站邢台一个人看的在线观看视频免费下载
  • 网校 039 网站建设多少钱优化公司网站排名
  • 软件免费下载的网站大全wordpress转换为html5
  • 合肥金融网站设计松原网站建设公司
  • 塘下春华网站建设邯郸二手房出售信息
  • 网站建设需求分析的功能大型网站建设优化排名
  • 莱芜哪家企业做网站企业网站如何进行定位
  • 青岛设计网站的公司餐饮装修公司
  • 自微网站首页主流网站建设技术
  • 网站空间的权限网页设计模板百度云
  • 免费商城系统网站建设莱芜大众网
  • 有了域名怎么建网站联系方式承德网站建设价格
  • 夏津网站建设wordpress 代码演示
  • 网站右侧浮动网站建设需要的设备和软件
  • thinkphp制作网站开发那些网站做任务领q币
  • 网站链接分析单位内网网站建设 开设栏目
  • 网站建设教程ppt网络舆情监测存在的问题
  • 九度网站建设wordpress 去google
  • 查询建设公司业绩网站做电子商务网站的总结
  • 厦门网站制作计划wordpress高级版
  • wordpress可以做电影网站吗策略网页游戏排行榜
  • 微信订阅号关键网站自助建站系统搭建网站
  • 网站logoico怎么做面包类网站设计
  • 平面设计师的网站凡科网小程序
  • wordpress主题demo导入东莞seo计费管理
  • 上海公司网站制作价格穿着西裤做的网站
  • 手机做任务的网站有哪些长春建设
  • 扬州网站建设外包东莞网络营销推广公司
  • 网站建设流程及费用网站建设的流程图示
  • asp.net 微网站开发教程网站的排版问题