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

合肥网站排名优化公司谷歌浏览器搜索引擎入口

合肥网站排名优化公司,谷歌浏览器搜索引擎入口,广州天河网站制作,wordpress定义字体上篇文章:Linux操作系统5-进程信号3(信号的捕捉流程,信号集,sigaction)-CSDN博客 本篇Gitee仓库:myLerningCode/l26 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 目录 一. 可重入…

上篇文章:Linux操作系统5-进程信号3(信号的捕捉流程,信号集,sigaction)-CSDN博客

本篇Gitee仓库:myLerningCode/l26 · 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com)

目录

一. 可重入函数

二. volatile关键字

2.1 volatile关键字作用

 2.2 中断程序下volatile关键字作用

三. SIGCHILD 信号

3.1 使用SIGCHLID处理进程退出

3.2 SIG_IGN清理僵尸进程


一. 可重入函数

我们一般将 main函数执行流和 信号捕捉执行流是两个执行流

有一个函数fun:

如果在main执行流和信号捕捉执行流中,这个函数被重复进入,如果出现了问题  -  则这个函数是不可重入函数。

如果在main执行流和信号捕捉执行流中,这个函数被重复进入,如果没有出现问题  -  则这个函数是可重入函数。

        不可重入函数如果在多个执行流中执行的话,可能会导致数据不安全问题

        是否可重入是一个中性的形容词。

一般来说:调用了malloc/free/new/delete等的函数是不可重入的 。调用了 I/O操作的函数也是不可重入的。

二. volatile关键字

2.1 volatile关键字作用

        vlolatile关键字的作用是:保证某变量的内存可见性。

        被vlolatile修饰的变量,系统总是从内存中读取这个数据。此时编译器不会对这个变量过度优化(比如将其写入到某一个寄存器中,从寄存器读取数据)。

 2.2 中断程序下volatile关键字作用

        下面这段代码可能会出现编译器过度优化而导致的错误。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>int quit = 0;void handler(int signo)
{printf("捕捉到[%d]信号\n", signo);printf("quit: %d", quit);quit = 1;printf("-> %d\n", quit);
}int main()
{signal(2, handler);while (!quit);printf("由于信号捕捉, quit为1 正常退出\n");return 0;
}

        该代码收到2号信号就会更改quit,然后进程就能正常结束

不优化情况下编译运行:

可以看到程序没有任何问题。

        现在增加编译器的优化, 修改makefile 增加 -O3

可以看到,ctrl c 之后进程收到2号信号将quit改为1,但是不会退出 。

为什么不会退出呢?数据会保存在内存或者寄存器

不优化:执行handler之后,将quit写回内存,main函数退出

优化:quit在main函数执行流没有被修改,编译器之后将其保存在寄存器中,且之后一直从寄存器中读取数据。执行handler之后,将物理内存中的quit改为1,但是寄存器中的数据没有修改,所以进程不会退出。

        这样就导致了代码无问题,程序有问题

如果对quit使用volatile关键字修饰,此时会保证其内存可见性(每次读取数据的时候都去内存中读取数据) 。之后就不会出问题了

#include <stdio.h>
#include <unistd.h>
#include <signal.h>volatile int quit = 0;void handler(int signo)
{printf("捕捉到[%d]信号\n", signo);printf("quit: %d", quit);quit = 1;printf("-> %d\n", quit);
}int main()
{signal(2, handler);while (!quit);printf("由于信号捕捉, quit为1 正常退出\n");return 0;
}

运行结果如下: 

三. SIGCHILD 信号

3.1 使用SIGCHLID处理进程退出

        SIGCHLID(17号)这个信号是子进程退出的时候会向父进程发送这个信号。

        我们在进程控制时候提到,可以使用wait或者waitpid来获取子进程退出的信息。处理僵尸进程(子进程退出,父进程太忙无时间处理子进程退出)问题。

        我们可以采用阻塞或者非阻塞的方式来等待子进程退出。采用阻塞的话,父进程就不能进行自己的工作。采用非阻塞的方式的话,进行自己工作的时候询问也会降低效率。

 进程等待可看这篇文章:Linux操作系统2-进程控制2(进程等待,waitpid系统调用,阻塞与非阻塞等待)_wait系统调用-CSDN博客

        我们使用子进程退出,父进程接收17号信号的特点。17号信号的默认行为是忽略,如果我们自定义17号信号的行为,在handler中进行等待子进程退出,这样就能让父进程去执行自己的代码而不用去浪费时间关心子进程退出了。

        即子进程退出,向父进程发送SIGCHILD信号,父进程接收信号后调用wait/waitpid清理子进程退出信息。清理僵尸进程。

测试代码如下:

        如果有多个子进程同时退出,或者部分子进程退出,需要循环等待它们,并且只要没等待成功就立即结束信号捕捉方法。

代码如下:

#include <iostream>#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <sys/types.h>void handler(int signo)
{// 处理子进程退出信息std::cout << "我是父进程 pid为:" << getpid() << "收到信号:" << signo << std::endl;while (1){int status = 0;pid_t sid = waitpid(-1, &status, 0);printf("子进程退出码[%d], 子进程退出信号[%d]\n", ((status >> 8) & 0xff), (status & 0x7f));if (sid <= 0)break;}
}int main()
{// 1.自定义SIGCHILD行为signal(SIGCHLD, handler);// 2.创建子进程pid_t id = fork();if (id == 0){// 子进程int cnt = 5;while (cnt--){std::cout << "我是子进程 pid为:" << getpid() << std::endl;sleep(1);}exit(2);}// 父进程int cnt = 0;while (1){std::cout << "我是父进程 pid为:" << getpid() << " 次数为:" << cnt++ << std::endl;sleep(1);}return 0;
}

3.2 SIG_IGN清理僵尸进程

        使用SIG_IGN清理僵尸是由于uinx的历史原因。在linux中保留了这种方式。

        我们使用signal或者sigaction将SIGCHILD信号的捕捉方法设置为SIG_IGN即可自动帮助我们清理僵尸进程。

测试代码如下:

         

#include <iostream>#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <sys/types.h>int main()
{// 1.自定义SIGCHILD行为,并用SIG_IGN清理僵尸进程signal(SIGCHLD, SIG_IGN);// 2.创建子进程pid_t id = fork();if (id == 0){// 子进程int cnt = 5;while (cnt--){std::cout << "我是子进程 pid为:" << getpid() << std::endl;sleep(1);}exit(2);}// 父进程不等待子进程int cnt = 0;while (1){sleep(1);}return 0;
}

测试僵尸进程有没有被处理。

 

如果我们注释掉 signal(SIGCHLD, SIG_IGN); 这条代码。

运行结果如下:

子进程没有受到处理变为僵尸进程,导致内存泄漏 

http://www.tj-hxxt.cn/news/21914.html

相关文章:

  • 网站的建设流程图淘宝流量
  • 网站建设目的与意义黄冈便宜的网站推广怎么做
  • 郑州做网站好可以发外链的网站整理
  • 做网站服务器 用mac pro 怎么样40个免费网站推广平台
  • 沈阳学网站制作学校软件开发app制作
  • 公司网站推广计划书广州网络推广哪家好
  • 推荐专业做网站公司平面设计培训费用一般是多少
  • 网络营销推广公司网站有哪些seo快速优化方法
  • 手机网站的推广房地产销售怎么找客户
  • 做海鲜团购网站百度图片搜索
  • 株洲网站建设费用网站建网站建设网站
  • 怎么重新网站做301百度seo排名工具
  • a做爰视频免费观费网站谷歌广告投放
  • 上海市网站设计seo企业优化顾问
  • 网站模板bootstrap绍兴seo优化
  • 临汾网站建设 吕梁网站建设武汉seo广告推广
  • 洛阳做网站太原seo建站
  • 外贸网站做啥网站优化哪个公司好
  • 珠海建设工程信息网站网络营销个人感悟小结
  • 晋城今日头条新闻seo工具包
  • 地板网站模板免费下载百度开发者平台
  • 代做毕业设计找哪个网站免费的外链平台
  • 做外贸进大公司网站今日新闻头条新闻
  • 网站建设的认识搜狗seo
  • 网站结构物理搜索引擎营销方法
  • 菏泽网站建设多少钱爱站工具包的主要功能
  • 怎样加入好大夫网站做医生百度客户服务电话
  • 建设银行住房公积网站公司网站怎么建立
  • 重庆江津网站建设广告投放平台排名
  • 湖南省郴州市宜章县常州百度seo排名