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

网站设计咨询电话广东新闻联播林红

网站设计咨询电话,广东新闻联播林红,山东市网站建设,编程培训机构名字当以一个进程结束时,它会变成僵尸进程,这个僵尸进程如果不处理,就会一直占用CPU资源,如果父进程要回收这个进程会通过进程等待的方式处理,回收子进程只会,会得到进程的退出信息 进程等待 父进程通过进程等…

当以一个进程结束时,它会变成僵尸进程,这个僵尸进程如果不处理,就会一直占用CPU资源,如果父进程要回收这个进程会通过进程等待的方式处理,回收子进程只会,会得到进程的退出信息


进程等待

父进程通过进程等待的方式,等待子进程运行结束,一般父进程使用wait或waitpid函数来等待子进程结束,子进程结束后,会将退出信息传递到wait或waitpid函数,从而被父进程获取


wait接口

使用wait需要包含头文件<sys/types.h>和<wait.h>

int wait(int* stat_loc); 

wait接受一个int类型指针,当wait结束后stat_loc会接收子进程返回的返回信息,wait函数会返回子进程的PID,

如果wait返回值大于零,说明wait函数等待到了子进程

如果wait返回值小于零,说明wait函数没有等待到子进程

我们来用一段代码演示一下

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main()
{pid_t id=fork();if(id==0){printf("我是子进程我的PID是:%d\n",getpid());int cnt=5;while(cnt){printf("%d\n",cnt);sleep(1);cnt--;}return 5;}int state=0;int num=wait(&state);printf("我是父进程,子进程退出码是%d,我的子进程PID是:%d\n",state,num);
}

运行结果如下

 

我们可以发现在fork后创建了一个子进程,父进程在子进程结束之前什么都没有做,一直等待子进程运行结束,这种状态就是父进程被堵塞了,我们称为阻塞等待,state接收了子进程返回的退出码,num接收了子进程返回的PID

wait返回了退出码之后为什么state的值是1280呢

wait返回值

wait运行完成后并不是直接把值传递给state的,而是通过操作state的二进制位来实现对state值的更改。

state是一个整形,有四个字节,对应32个比特位

我们来看这幅图

其中 

其中黄色的部分wait不会操作,我们不需要管

蓝色部分是退出码部分

橙色部分是退出信息部分

我们要从state中得到退出码和退出信息,可以分别通过以下两种方式

 退出码:(state>>8 & 0xFF)

退出信息:state & 0x7F 

我们用代码测试一下 

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main()
{pid_t id=fork();if(id==0){printf("我是子进程我的PID是:%d\n",getpid());int cnt=5;while(cnt){printf("%d\n",cnt);sleep(1);cnt--;}return 5;}int state=0;int num=wait(&state);int sig=state&0x7F;int eit=(state>>8) & 0xFF;printf("我是父进程\n");printf("我的子进程PID是:%d\n",num);printf("我的子进程退出码是:%d\n",eit);printf("我的子进程退出信息是:%d\n",sig);
}

运行结果如下

 

这里退出码的计算结果刚好对应了代码中返回的数值,子进程是正常退出的,所以退出信息就是0

Linux系统给我们提供了三个个宏,用于检测wait参数的state

分别是:

WIFSIGNALED:检测进程是否因为信号而终止的宏定义,是返回true,否则返回false

WIFEXITED:检测进程是否正常退出的宏定义,如果正常退出返回true,否则返回false

WEXITSTATUS:提取子进程退出码,也就是8~15位的state

我们来用代码测试一下

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{pid_t id=fork();if(id==0){printf("我是子进程我的PID是:%d\n",getpid());int cnt=5;while(cnt){printf("%d\n",cnt);sleep(1);cnt--;}return 5;}int state=0;int num=wait(&state);if(WIFEXITED(state)){printf("exit code = %d\n",WEXITSTATUS(state));}else{printf("子进程异常退出...\n");}
}

运行结果

 

进程正常退出WIFEXITED返回true,进入条件语句,return 5 ,WEXITSTATUS计算state从而得出返回码为5 

 waitpid返回值

waitpid和wait差不多都是用来阻塞父进程,等待子进程返回的函数,但是如果父进程有多个子进程wait只会等待第一个结束的进程,并将其回收,waitpid的优点在于它可以等待用户指定的PID的子进程,等待其结束

 函数原型

#include<sys/wait.h>
#include<sys/types.h>
pid_t waitpid(pid_t pid,int* status,int* option);

 我们来用代码测试一下功能

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{pid_t id1=fork();if(id1==0){printf("child1的PID:%d\n",getpid());sleep(5);return 0;}pid_t id2=fork();if(id2==0){printf("child2的PID:%d\n",getpid());sleep(5);return 0;}int state;int ret=wait(&state);printf("wait is come PID:%d\n",ret);sleep(10);return 0;
}

让我么运行并检查一下所有的进程信息

while true; do ps axj | head -1 && ps axj | grep text3 | grep -v grep;sleep 1; done

 代码运行结果

检查结果 

 

我们能看到一开始父进程就创建了两个进程,这里显示了三个进程的信息

但是只有第一个创建的子进程的被父进程等待到了,并且在这个进程运行结束之后将它的僵尸进程回收

 然后我们再来实验一下waitpid函数

将wait函数改为waitpid函数,并且使用id2的值

 代码示例

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{pid_t id1=fork();if(id1==0){printf("child1的PID:%d\n",getpid());sleep(5);return 0;}pid_t id2=fork();if(id2==0){printf("child2的PID:%d\n",getpid());sleep(5);return 0;}int state;int ret=waitpid(id2,&state,0);printf("wait is come PID:%d\n",ret);sleep(10);return 0;
}

运行结果

 

虽然id2不是第一个创建的进程,但最后waitpid还是将id2的进程回收了 

waitpid的阻塞等待,选择阻塞等待的waitpid,它的参数列表中的第三个参数option的值为零,阻塞等待waitpid会一直等待用户给waitpid传递的值为PID的进程,如果waitpid一直没有等待到相应的子进程运行结束,那么父进程将不会运行后面的代码,将一直阻塞在waitpid这一行,而

 waitpid的非阻塞等待,选择非阻塞等待的waitpid,它的参数列表中的第三个参数option的值为WNOHANG,非阻塞等待waitpid进行一次没有等待到子进程的运行结束,那么waitpid就结束,父进程进行下面的代码,非阻塞等待如果未等到进程的结束,那么返回0,等待到进程结束,返回进程的PID,如果没有对应的子进程会返回负数

我们来通过一份代码来演示一下非阻塞等待的作用

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{pid_t id1=fork();if(id1==0){sleep(5);return 0;};int state;while(1){int num=waitpid(id1,&state,WNOHANG);if(num==0){printf("等待失败,进程继续\n");}else if(num>0){printf("等待成功,子进程PID:%d\n",num);break;}else{printf("等待发生错误\n");break;}sleep(1);}return 0;
}

运行结果

 

我们可以看到,子进程需要5秒结束,在这5秒期间,waitpid接收不到子进程结束的信号,所以父进程一直向下面的代码运行,当子进程运行结束后,waitpid接收到了结束信号 

 


文章转载自:

http://E31UOIXj.dzdtj.cn
http://WNZlt8cb.dzdtj.cn
http://qPczzVEr.dzdtj.cn
http://Hg5NiVqF.dzdtj.cn
http://iqhqGNJB.dzdtj.cn
http://RUvKLWCV.dzdtj.cn
http://KQ7oR3f4.dzdtj.cn
http://TyE1ssGM.dzdtj.cn
http://MPgK8biY.dzdtj.cn
http://r4G3nnsb.dzdtj.cn
http://kmoYcef1.dzdtj.cn
http://fiB3maxi.dzdtj.cn
http://tIqpgSGM.dzdtj.cn
http://1hkMuNBK.dzdtj.cn
http://D8JxIO6M.dzdtj.cn
http://jpV32aTf.dzdtj.cn
http://y04nqrLn.dzdtj.cn
http://JIxy6g4m.dzdtj.cn
http://GWi64TB1.dzdtj.cn
http://H0QS53KR.dzdtj.cn
http://lCyXFbF0.dzdtj.cn
http://1OfiOdwM.dzdtj.cn
http://cM3ljYWp.dzdtj.cn
http://TsLvCr0I.dzdtj.cn
http://EYvCgWqd.dzdtj.cn
http://NfTmxF3v.dzdtj.cn
http://5D4KKA87.dzdtj.cn
http://85k5I2T9.dzdtj.cn
http://ld2N3cFM.dzdtj.cn
http://339R7TKD.dzdtj.cn
http://www.dtcms.com/wzjs/619691.html

相关文章:

  • 网站后台编辑器不显示火车头wordpress自动排版
  • 商城网站主机装修贷
  • 昆明网站制作前十企业网站模板 优帮云
  • 学习网站开发技术百度词条优化工作
  • 买的网站模板会影响深圳做app网站建设
  • 网站首页权重国内网站建设代理
  • 扬州大发网站建设wordpress附件修复
  • 广西南宁电商网站建设抖音代运营服务协议
  • 专业网页设计和网站制作公司中信建设有限责任公司临空经济区
  • 个体工商户经营范围网站开发wordpress首页模块修改
  • 做网站一个月多少钱专业做农牧应聘的网站
  • 旅游网站系统设计wordpress模板top破解版
  • 制作手机网站什么软件焦作企业网站建设
  • 手机网站制作软件下载宝塔网站301重定向怎么做
  • 两人做性视频网站手机棋牌app软件开发
  • 网站关键词几个建设通网站是什么网站
  • 简述网站建设流程网站开发一个模板费用
  • 做网站一班需要多少钱wordpress文章只显示题目
  • 官网网站源码模板网站的缺点
  • 专业的网站建设公网站如何收费
  • 晋城市 制作网站企业门户网站建设市场
  • 工具站seoartisteer 做的网站
  • 计算机机应用网站建设与维护浅谈阿里企业的电子网站建设
  • 移动网站建设推荐网站开发宣传广告
  • 新手学网页设计的网站wordpress 纯净版下载地址
  • 网站建设的项目计划阿克苏网站建设服务
  • 网站群建设管理办法网站建设实施流程
  • 在腾讯云怎样建设网站成功营销十大经典案例
  • c mvc制作网站开发乐山市规划和建设局门户网站
  • 学校网站维护seo软文代写