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

帮别人做彩票网站沈阳网络营销推广的公司

帮别人做彩票网站,沈阳网络营销推广的公司,免费创建个人商城网站,专业网站设计制作价格前言:接着前面进程终止,话不多说我们进入Linux进程等待的学习,如果你还不了解进程终止建议先了解: Linux进程终止 本篇主要内容: 什么是进程等待 为什么要进行进程等待 如何进程等待 进程等待 1. 进程等待的概念2. 进…

前言:接着前面进程终止,话不多说我们进入Linux进程等待的学习,如果你还不了解进程终止建议先了解:

Linux进程终止


在这里插入图片描述


本篇主要内容:
什么是进程等待
为什么要进行进程等待
如何进程等待

在这里插入图片描述


进程等待

  • 1. 进程等待的概念
  • 2. 进程等待必要性
  • 3. 进程等待的方法
    • 3.1 wait方法
    • 3.2 waitpid方法
  • 4. 获取子进程status
    • 获取子进程退出信息
  • 5. waitpid的第三个参数options
  • 6. 总结拓展


1. 进程等待的概念

首先在开始之前我们提个问题,到底什么是进程等待?

进程等待的概念:

  • 我们通常说的进程等待其实是通过wait/waitpid的方式,让父进程(一般)对子进程进行资源回收的等待过程,父进程必须等待这个子进程结束后,处理它的代码和数据!

2. 进程等待必要性

在了解完进程等待的概念后,新的问题出现了,我们为什么要进行进程等待,进程等待的必要性是什么?

进程等待必要性:

  • 若子进程退出,而父进程对它不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
  • 进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,谁也没有办法杀死一个已经死去的进程。
  • 父进程创建子进程的目的是为了让子进程协助自己完成任务的,而父进程需要知道子进程将任务完成得如何。这就需要通过进程等待的方式,获取子进程的退出信息。

3. 进程等待的方法

3.1 wait方法

我们可以通过系统调用来等待进程:wait函数

wait等待任意一个子进程的退出,如果等待成功他将返回子进程的pid,失败则返回-1

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

我们就用一段代码来看看wait:

   #include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/wait.h>void Worker(){int cnt = 5;while(cnt){printf("i am child, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt--);sleep(1);}}int main(){                                                                                                                                                                                      pid_t id = fork();if(id == 0){// childWorker();exit(0);}else{sleep(10);// fatherpid_t rid = wait(NULL);if(rid == id){printf("wait success, pid: %d\n", getpid());}}return 0;}

进程等待:wait函数

我们通过视频发现:进程等待是可以回收子进程僵尸状态的


然后我们将父进程sleep()取消,看看在子进程退出之前父进程在干什么

   #include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/wait.h>void Worker(){int cnt = 5;while(cnt){printf("i am child, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt--);sleep(1);}}int main(){                                                                                                                                                                                      pid_t id = fork();if(id == 0){// childWorker();exit(0);}else{// fatherprintf("wait before:\n");pid_t rid = wait(NULL);printf("wait after:\n");if(rid == id){printf("wait success, pid: %d\n", getpid());}sleep(10);}return 0;}

观察父进程等待过程

通过这个视频我们又能发现两个进程一起运行,但是在子进程没有退出之前,父进程一直在wait上等待,并且并没有出现子进程僵尸状态而是直接回收了。

结论:如果子进程根本就没有退出,父进程必须在wait上进行阻塞等待。直到子进程僵尸,wait自动回收返回。


3.2 waitpid方法

waitpidwait都是等待进程。waitpid可以指定等待一个进程,且有三个参数
在这里插入图片描述
在这里插入图片描述


4. 获取子进程status

父进程想要知道子进程的退出信息,也就是退出码和退出信号,就要用到输出型参数status

  • wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果传递NULL,表示不关心子进程的退出状态信息。
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
int main(){                                                                                                                                                                                      pid_t id = fork();if(id == 0){// childWorker();exit(10); // 设置成10方便观察现象}else{// fatherprintf("wait before:\n");int status = 0;pid_t rid = waitpid(id, &status, 0);printf("wait after:\n");if(rid == id){printf("wait success, pid: %d, status: %d\n", getpid(), status);}}return 0;}

在这里插入图片描述

在这里插入图片描述

我明明将exit的退出结果设置成10,但是为什么他的status会是2560呢?

  • 其实status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位)

在这里插入图片描述
在这里插入图片描述
因此我们在研究status时,不能整体使用status!!!


获取子进程退出信息

因为我们知道了status不能整体使用因此我们要进行位操作:


exit sig: status&0x7f //获取信号exit code: (status>>8)&0xff //获取退出结果
  • 当我们的程序异常了,exit code 将无任何意义
  • exit sig : 0则代表没有收到信号
  • 手动杀掉子进程也会获取到信号

但是如果我们每次提取退出信息都要使用繁琐的位运算,这很不方便,因此系统给我们做了一个简单的封装

status:

  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
int main()
{pid_t id = fork();if(id == 0){// childWorker();exit(1);}else{// sleep(10);// fatherprintf("wait before:\n");//pid_t rid = wait(NULL);                                                             int status = 0;                              pid_t rid = waitpid(id, &status, 0);   printf("wait after:\n");if(rid == id)                       {                           // 不能对status整体使用//printf("wait success, pid: %d, rpid: %d, exit sig: %d, exit code: %d\n",getpid(), rid, status&0x7f, (status>>8)&0xff);if(WIFEXITED(status)){printf("child process normal quit, exit code: %d\n", WEXITSTATUS(status));}                                                    else{                                         printf("child process quit exept!!!\n");}}}                                                                                                                                                                                  return 0;
}            

在这里插入图片描述


当我们要获取多个进程的调度信息时,我们给每个进程都要一个编号,我们来观察一下进程是怎样调度的

void Worker(int number)
{int cnt = 5;while(cnt){printf("i am child, pid: %d, ppid: %d, cnt: %d, number: %d\n", getpid(), getppid(), cnt--, number);sleep(1);}
}
const int n = 10;int main()
{for(int i = 0; i < n; i++){pid_t id = fork();if(id == 0)                 {              Worker(i);                  exit(i);}                                                                                                                                                                              }                                                                                                                 // 等待多个子进程                 for(int i = 0; i < n; i++)                        {                                         int status = 0;                                                                                                   pid_t rid = waitpid(-1, &status, 0); //pid > 0, -1:等待任意一个进程if(rid > 0){printf("wait child %d success, exit code: %d\n", rid, WEXITSTATUS(status));}}return 0;}

观察进程调度顺序

我们发现明明是按顺序创建的进程,但是在调度时却没有顺序可言,终止的时候也没有顺序,因为进程在调度完全由调度器说的算,所以进程调度的先后我们并不确定,这点在前面我们也提到过。


5. waitpid的第三个参数options

在使用waitpid的第三个参数时,前面我们提到设为0则是默认阻塞等待状态,必须等待子进程的退出,当时如果我们要做自己的事我们就不能使用0而是使用:WNOHANG

options:

  • WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
  • 0:默认的阻塞等待状态

**父进程在非阻塞等待时,因为子进程没有结束,就跑去做自己的事情了,但是又要继续等待,所以往往伴随着重复调,轮询,也就是基于非阻塞轮询的等待方案!
**


我们来直接验证一下非阻塞等待:

void Worker(int cnt)
{printf("i am child, pid: %d, cnt: %d\n", getpid(), cnt);sleep(1);
}
int main()
{pid_t id = fork();if(id == 0){// 子进程int cnt = 5;while(cnt){Worker(cnt);sleep(1);cnt--;}exit(1);}// 父进程while(1){int status = 0;pid_t rid = waitpid(id, &status, WNOHANG);if(rid > 0)                                                                                                                                                                    {// 等待成功printf("wait success, child quit, exit code: %d, exit sig: %d\n", (status>>8)&0xff, status&0x7f);break;}else if(rid == 0){// 等待成功,但子进程并未退出printf("wait again, child alive, do other thing\n");                                                                                                                       sleep(1);}else{// 等待失败printf("wait failed\n");break;} } return 0;}

在这里插入图片描述
我们可以看到非阻塞等待可以让我们的父进程在等待时,做自己的事!


6. 总结拓展

拓展一:父进程如何得知子进程的退出信息
在这里插入图片描述
父进程调用wait()/waitpid()来获取子进程的退出信息,调用的接口就传入了一个status参数,而父进程中存在着一个statusp的指针。

而子进程在退出时,操作系统就会将退出信号和退出码写到子进程的PCD中

int exit_code;
int exit_signal

而退出信号和退出码将会写到这两个变量中,
当我们调用系统调用时,只需要将这两个变量组合写入到变量里

*statusp = (exit code<<8)| exit siganl

这样父进程就获取到了子进程的退出信息


拓展二:我们为什么不用全局变量获取子进程的退出信息而用系统调用?

这个就是因为进程具有独立性,父进程无法直接获得子进程的退出信息


总结:

进程等待确实非常有用,它既可以回收僵尸进程,避免造成内存泄漏,也能让父进程能够获取到子进程的退出信息,进程等待我们就先了解这么多,进程控制马上就到了我们的最后一步——进程替换,让我们来期待下一篇!

谢谢大家支持本篇到这里就结束了
在这里插入图片描述


文章转载自:
http://dinncoandrostenedione.bpmz.cn
http://dinncosubapostolic.bpmz.cn
http://dinncoextramusical.bpmz.cn
http://dinncoroadstead.bpmz.cn
http://dinncocrowberry.bpmz.cn
http://dinncotrichothecin.bpmz.cn
http://dinncosickroom.bpmz.cn
http://dinncopenthouse.bpmz.cn
http://dinncomaterfamilias.bpmz.cn
http://dinncodecadence.bpmz.cn
http://dinncoionomer.bpmz.cn
http://dinncoorthotic.bpmz.cn
http://dinncoreadmission.bpmz.cn
http://dinncoshaddup.bpmz.cn
http://dinncobearskinned.bpmz.cn
http://dinncobarege.bpmz.cn
http://dinnconoam.bpmz.cn
http://dinncocrura.bpmz.cn
http://dinncotarheel.bpmz.cn
http://dinncotitrimetry.bpmz.cn
http://dinncoconicoid.bpmz.cn
http://dinncoeximious.bpmz.cn
http://dinncoazo.bpmz.cn
http://dinncolapsible.bpmz.cn
http://dinncowinepress.bpmz.cn
http://dinncoabase.bpmz.cn
http://dinncofly.bpmz.cn
http://dinncosaccharide.bpmz.cn
http://dinncoscytheman.bpmz.cn
http://dinncojimp.bpmz.cn
http://dinncoblockish.bpmz.cn
http://dinncocytochrome.bpmz.cn
http://dinncomoratory.bpmz.cn
http://dinncohassle.bpmz.cn
http://dinncodisillusionment.bpmz.cn
http://dinncofattest.bpmz.cn
http://dinncozygology.bpmz.cn
http://dinncoeasy.bpmz.cn
http://dinncoexperimenter.bpmz.cn
http://dinncoinclusion.bpmz.cn
http://dinncobrugge.bpmz.cn
http://dinncobutane.bpmz.cn
http://dinncophoebus.bpmz.cn
http://dinncochromic.bpmz.cn
http://dinncohumiliation.bpmz.cn
http://dinncopolyacrylamide.bpmz.cn
http://dinncowinehouse.bpmz.cn
http://dinncoavp.bpmz.cn
http://dinncohemipode.bpmz.cn
http://dinncoyeastlike.bpmz.cn
http://dinncogrunion.bpmz.cn
http://dinncoyamasee.bpmz.cn
http://dinncodeacidify.bpmz.cn
http://dinncopungent.bpmz.cn
http://dinncopotboiler.bpmz.cn
http://dinncobowleg.bpmz.cn
http://dinncotinker.bpmz.cn
http://dinncomyositis.bpmz.cn
http://dinncoman.bpmz.cn
http://dinncotense.bpmz.cn
http://dinncodoggish.bpmz.cn
http://dinncocovariation.bpmz.cn
http://dinncoleaning.bpmz.cn
http://dinncobluebutton.bpmz.cn
http://dinncowicked.bpmz.cn
http://dinncoinexistent.bpmz.cn
http://dinncoaurelian.bpmz.cn
http://dinncomoonish.bpmz.cn
http://dinncomixen.bpmz.cn
http://dinncofertilization.bpmz.cn
http://dinncophaeacian.bpmz.cn
http://dinncouromere.bpmz.cn
http://dinncopolemicist.bpmz.cn
http://dinncoparapet.bpmz.cn
http://dinncoomnipresent.bpmz.cn
http://dinncozairese.bpmz.cn
http://dinncoteller.bpmz.cn
http://dinncohectocotylus.bpmz.cn
http://dinncopollute.bpmz.cn
http://dinncoepilog.bpmz.cn
http://dinncoskycap.bpmz.cn
http://dinncoexceedingly.bpmz.cn
http://dinncojewelweed.bpmz.cn
http://dinncophoneticise.bpmz.cn
http://dinncoupspring.bpmz.cn
http://dinncowhomever.bpmz.cn
http://dinncofrigga.bpmz.cn
http://dinncomed.bpmz.cn
http://dinncoshort.bpmz.cn
http://dinncosclerometer.bpmz.cn
http://dinncocaudate.bpmz.cn
http://dinncoconfidingly.bpmz.cn
http://dinncoresponsor.bpmz.cn
http://dinncophototypy.bpmz.cn
http://dinncohaleness.bpmz.cn
http://dinncomhl.bpmz.cn
http://dinncoambeer.bpmz.cn
http://dinncounderpants.bpmz.cn
http://dinncomoderate.bpmz.cn
http://dinncoalkaline.bpmz.cn
http://www.dinnco.com/news/155042.html

相关文章:

  • 做游戏网站多钱宁波seo推广服务
  • ps做网站心得友情链接论坛
  • 龙川县建设网站平台代运营是什么意思
  • 冲压加工瑞安有做网站吗微信怎么推广引流客户
  • 广告制作平台有哪些seo是搜索引擎优化
  • 怎么做倒计时网站正规优化公司哪家好
  • 网站开发的未来展望seo算法培训
  • 山西省建设部网站企业网站的主要类型有
  • 如何提高网站的收录辅导班
  • 济南做网站的快速网站排名优化
  • 手机企业网站制作企业seo自助建站系统
  • 连云港网站建设做一个企业网站需要多少钱
  • 苍南县龙港哪里有做网站站内推广的方法
  • 网站建设站点标题在什么位置域名注册管理中心网站
  • 东莞网站建设哪里好培训心得体会万能模板
  • 电脑网站加速器自己怎么做游戏推广赚钱
  • 北京电商网站开发价格seo快速排名软件品牌
  • 推广普通话的文章seo排名优化的网站
  • 江西万通建设有限公司网站手机google官网注册账号入口
  • 浙江网站建设推广公司找哪家北京seo推广公司
  • 潍坊做网站教程舆情分析网站免费
  • 接做图网站网络营销工具及其特点
  • 公司有域名 如何做网站yoast seo教程
  • 门户网站做免费相亲的合肥网络公司seo
  • 綦江集团网站建设浏览器下载大全
  • 广东网站建设人员百度标记号码认证平台
  • 官网怎么注册手机网站排名优化软件
  • 个人新闻类网站模板免费下载优化的含义是什么
  • 做网站每年需要购买域名吗线下引流推广方法
  • 做批发服装的网站seo属于技术还是营销