Linux编程基础 3.3:进程同步

1 wait函数

#include <sys/wait.h>
pid_t wait(int *status);

功能:挂起进程,进程进入阻塞状态,直到子进程变为僵尸态,如果捕获到子进程的退出信息就会转为运行态,然后回收子进程资源并返回;若没有变为僵尸态的子进程,wait函数就会让进程一直阻塞。若当前进程有多个子进程,只要捕获到一个变为僵尸态的子进程,wait函数就会恢复执行态。

参数说明:参数status是一个int *类型的指针,用来保存子进程退出时的状态信息。通常情况下该参数设为NULL,表示不关心进程时如何终止的。

返回值说明

  • 成功:返回子进程的进程id;
  • 失败:返回-1,errno被设置为ECHILD。

【案例 1】若子进程p1p_1p1是其父进程ppp的先决进程,基于wait函数使得进程同步。

test_wait.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(){pid_t tempPid, tempW;tempPid = fork();if(tempPid == -1){perror("fork error");exit(1);}else if(tempPid == 0){//childsleep(3);printf("Child process, pid = %d, ppid = %d\n", getpid(), getppid());}else{//parent tempW = wait(NULL);printf("Catched a child process, pid = %d, ppid = %d\n", tempW, getppid());}//of ifprintf("......finish......");return 0;
}//of main

若wait函数的参数不为空,可以获取子进程的退出状态,退出状态存放在参数status的低八位中。Linux定义了一组判断进程退出状态的宏函数,其中最基础的两个是:

#include <sys/wait.h>
int WIFEXITED(int status);//判断子进程是否正常退出,若是,返回非0值,否则返回0
int WEXITSTATUS(int status);//和WIFEXITED配合使用,WIFEXITED返回非0值,则使用该宏提取子进程的返回值。

【案例 2】使用wait同步进程,并使用宏获取子进程的返回值。

test_wait2.c
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(){int tempStatus;pid_t tempPid, tempW;tempPid = fork();if(tempPid == -1){perror("fork error");exit(1);} else if(tempPid == 0){//子sleep(3);printf("Child process: pid=%d\n",getpid());exit(5);}  else{//父tempW = wait(&tempStatus);if(WIFEXITED(tempStatus)){printf("Child process pid=%d exit normally.\n", tempW );printf("Return Code:%d\n",WEXITSTATUS(tempStatus));} else {printf("Child process pid=%d exit abnormally.\n", tempW);}//of if}//of ifreturn 0;
}//of main

2 waitpid函数

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

功能
wait函数的缺点:当前进程有很多个子进程,wait函数无法保证所有子进程在父进程之前执行。
waitpid函数:可以应对 wait函数面临的缺点。可以等待指定的子进程,也可以在父进程不阻塞的情况下获取子进程的状态。
参数说明

  • pid:一般是进程的pid,也有可能是其他取值。进一步说明如下:
    – pid > 0:等待子进程(编号为pid)退出,若退出,函数返回;若未结束,则一直等待;
    – pid = 0:等待同一进程组的所有子进程退出,若某子进程加入了其他进程组,则waitpid不再关心它的状态;
    – pid = -1:waitpid函数退化为wait函数,阻塞等待并回收一个子进程;
    – pid < -1:等待指定进程组中的任何子进程,进程组的id等于pid的绝对值。
  • options: 提供控制选项,可以是一个常量,也可以是|连接的两个常量,选项如下:
    – WNOHANG:如果子进程没有终止,waitpid不会阻塞父进程,会立即返回;
    – WUNTRACED:如果子进程暂停执行,waitpid立即返回;
    – 0:不使用选项。
    返回值说明
  • 成功:返回捕捉到的子进程id;
  • 0:options = WNOHANG, waitpid发现没有已退出的子进程可回收;
  • -1:出错,errno被设置。

【案例 3】父进程等待进程组中指定子进程,该进程不退出,则父进程一直阻塞。

test_waitpid.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(){pid_t tempPid, tempP, tempW;tempPid= fork();							//创建第一个子进程if (tempPid == -1){							perror("fork1 error");exit(1);} else if (tempPid == 0){						//子进程沉睡sleep(5);printf("First child process:pid=%d\n", getpid());} else {						//父进程继续创建进程int i;tempP = tempPid;for (i = 0; i < 3; i++){					//由父进程创建3个子进程if ((tempPid = fork()) == 0){break;}//of if}//of for iif (tempPid == -1){						//出错perror("fork error");exit(2);} else if (tempPid == 0){					//子进程printf("Child process:pid=%d\n", getpid());exit(0);} else {					//父进程tempW = waitpid(tempP, NULL, 0);			//等待第一个子进程执行if (tempW == tempP){printf("Catch a child Process: pid=%d\n", tempW);}else{printf("waitpid error\n");}//of if}//of if}//of ifreturn 0;
}//of main

【案例 4】基于waitpid函数不断获取子进程的状态。

test_waitpid2.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {pid_t tempPid, tempW;tempPid = fork();if (tempPid == -1){perror("fork error");exit(1);} else if (tempPid == 0){sleep(3);printf("Child process:pid=%d\n", getpid());exit(0);} else {do{tempW = waitpid(tempPid, NULL, WNOHANG);if (tempW == 0){printf("No child exited\n");sleep(1);}//of if} while (tempW == 0);if (tempW == tempPid){printf("Catch a Child process:pid=%d\n", w);}else{printf("waitpid error\n");}//of if}//of ifreturn 0;
}//of main

3 特殊进程的危害

  • 僵尸进程不能再次被运行,会占用一定的内存空间,并占据进程编号,当僵尸进程较多时,将会消耗系统内存,新进程可能因内存不足或无法获取pid而无法创建;
  • 父进程通过wait()和waitpid()函数可以有效防止僵尸进程的产生,对于已存在的僵尸进程,则可通过杀死其父进程的方法解决;
  • 当僵尸进程的父进程被终止后,僵尸进程将作为孤儿进程被init进程接收,init进程会不断调用wait()函数获取子进程状态,对已处于僵尸态的进程进行处理;
  • 孤儿进程永远不会成为僵尸进程。

4 小结

进程创建fork
进程管理exec函数族
进程同步wait,waitpid

5 课后编程作业

  • 创建一个子进程,使父子进程分别打印不同的内容;
  • 创建一个子进程,使子进程通过exec更改代码段,执行cat命令。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单代号网络图计算例题_如何把横道图转化成双代号网络图?

横道图一般都是用Project或者表格做的&#xff0c;下面就用斑马进度计划软件介绍一下怎么将横道图转化为双代号网络图使用工具&#xff1a;广联达斑马进度计划&#xff0c;点击进入官网下载使用Excel表格绘制的横道图&#xff0c;如何快速转化成网络图打开斑马进度计划软件&…

satd残差_RDO、SAD、SATD、λ相关概念【转】

率失真优化概述&#xff1a;率失真优化(Rate D isto r t i on Op t i m ized)策略是在率失真理论[3 ]的基础上提出的一种代价函数方案,  RDO 的主要思想是, 在计算代价函数时, 同时考虑码率和失真度两方面因素的制约, 在保证低失真度的同时保证低码率, 这样更加有利于视频流的…

excel表格不够怎么添加_excel怎么添加筛选

常用的表格处理软件就是excel表格&#xff0c;有时候一些excel上面会有很多不同类型的东西需要筛选以便更能方便寻找&#xff0c;那么excel怎么添加筛选呢&#xff1f;小编跟大家详细介绍。excel怎么添加筛选步骤1&#xff1a;首先&#xff0c;打开一篇你需要选择的Excel步骤2&…

Linux编程基础 4.1:系统调用

1简介 信号&#xff1a;软中断信号&#xff0c;是软件层次上对中断的一种模拟&#xff0c;用于提醒进程事件的发生。 用户比较容易控制的信号发送方式有&#xff1a; 组合按键方式&#xff1b;Shell命令方式&#xff1b;系统调用&#xff1a;kill、raise、abort等。 本部分主…

createsemaphore 异常_浅析SPC之异常分析

未来能源的短缺及资源匮乏&#xff0c;导致各国都在寻求替代能源以避免发生无资源可用的情况。汽油替代能源—生质酒精由此得到了广泛的应用。生质酒精属于生质燃料(Biofuel)的一种&#xff0c;是由生物或化学转换成生物质(biomass)而取得的原料。它能够延长零件的使用寿命&…

Linux编程基础 4.2:软件条件

3 软件条件 当满足某种软件条件时&#xff0c;也可以驱使内核发送信号。 alarm setitimer 3.1 alarm函数 #include <unistd.h> unsigned int alarm(unsigned int seconds);函数功能&#xff1a; 相当于计时器&#xff0c;驱使内核在指定秒数后发送信号到调用该函数的…

layui 如何去dom_常用元素操作 - layui.element

元素功能的开启只需要加载element模块即会自动完成&#xff0c;譬如tab选项卡切换、导航菜单滑动切换效果、面包屑导航、进度条等&#xff0c;使用这些小交互功能的前提就是&#xff1a;拥有符合这些小功能的所需正确的HTML结构&#xff0c;以及加载element模块&#xff1b;如下…

苹果5越狱教程_unc0ver5.2.0安装方法 iOS13.5用Cydia Impactor或AltStore越狱教程

unc0ver5.2.0是最新更新出来的越狱手机系统&#xff0c;这次的更新不仅仅只是修复了系统的稳定性&#xff0c;大家在更新之后可以支持iOS13.5.5Beta/iOS13.6Beta的使用&#xff0c;所有使用苹果手机的用户想要使用的话可以看下面的详细安装教程&#xff0c;为大家介绍详细的操作…

Linux编程基础 4.3:信号阻塞

4 信号阻塞 在进程PCB中存在两个信号集&#xff1a;信号掩码&#xff08;signal mask&#xff09;、未决信号集&#xff08;signal pending&#xff09;。 两个信号集都是位图&#xff0c;每一位对应一个信号&#xff1a; 若mask中某个位被设置为1&#xff0c;则对应的信号将…

# 定义四边形_【四边形系列专题】 特殊平行四边形之矩形

点击上方蓝字关注我们【四边形系列专题】特殊平行四边形之矩形TSQ中学数学微信&#xff1a;TSQmaths一、知识网络二、重难突破知识点一 矩形的性质及应用1、定义&#xff1a;有一个角是直角的平行四边形叫做矩形&#xff0e;注意&#xff1a;1、对称性&#xff1a;矩形是轴对称…

xs资料网-产品设计图档下载_proe玩具车3D模型图档下载creo4.0汽车模型下载中磊教育...

现在设计产品的还是有相当一大部分人是用proe造型的&#xff0c;之前我们一直做的是UG的产品造型&#xff0c;今天给大家介绍一款玩具车的3d模型&#xff0c;喜欢的可以下载下载自己研究研究&#xff0c;中磊教育产品设计教程proe玩具车3D模型图档是通过曲面造型所绘制的零件&a…

Linux编程基础 4.4:信号捕获

5 信号捕获 信号的产生是异步事件&#xff0c;进程不知道信号何时会递送&#xff0c;也不会等待信号到来。 进程可以为信号注册信号处理函数来实现自定义动作。 进程的信号在内核态处理&#xff0c;内核为每个进程准备了一个信号向量表&#xff0c;记录每个信号所对应的处理机…

苹果7手机严重卡顿_分享苹果手机最实用的7个技巧,各个精心挑选,不知道真的太亏了...

使用苹果手机这么久了&#xff0c;你一定也发现了不少好用的功能&#xff0c;今天就来分享苹果手机最实用的7个技巧&#xff0c;每个都是精心挑选&#xff0c;不要错过&#xff0c;总有一个是你需要的。1、 三指操作在编辑文档的时候&#xff0c;三指左滑是撤销(上一步编辑撤销…

实验一:系统编程开发环境实验

一【实验目的】 1.熟悉Linux开发环境&#xff1b; 2.掌握Linux程序编译调试方法&#xff1b; 3.理解文件I/O通用操作&#xff0c;掌握内核函数的基本用法&#xff1b; 4.支撑网络空间安全专业的专业核心能力、综合创新能力。 二【实验要求】 以下每个实验均要求&#xff1a;…

如何获取大端中的数据_【软件】ProE中各种获取数据方式的区别

更多精彩&#xff0c;请点击上方蓝字关注我们&#xff01;软件ProE中各种获取数据方式的区别输入特征&#xff1a;输入特征是通过数据共享功能从外部文件输入几何的&#xff0c;文件输入以后&#xff0c;会转换成proe软件能够识别的几何&#xff0c;称为一个特征发布几何&#…

实验二:文件操作编程实验

一【实验目的】 1.掌握文件或目录属性信息的函数stat()函数的使用&#xff1b; 2.掌握目录操作的函数opendir 函数和readdir函数的使用&#xff1b; 3.编写程序mysearch.c递归实现打印输出任意目录下&#xff0c;指定类型的所有文件&#xff0c;如&#xff1a;./mysearch /hom…

数字类 default 0和 default 0_全方位的数字规划工具Visual Components 4.0 数字化工厂仿真软件...

Visual Components 是全方位的数字规划工具。无论从制程规划、生产到营销都能够整合在同一个平台上作业&#xff0c;有助于内部的技术沟通及外部营销。此外&#xff0c;Visual Components 整合了物流及机器人模拟功能&#xff0c;帮助企业在研发前期即可进行产能确认&#xff0…

python中写入csv文件的方法_Python写入CSV文件的方法

python笔记5-python2写csv文件中文乱码问题前言python2最大的坑在于中文编码问题&#xff0c;遇到中文报错首先加u&#xff0c;再各种encode、decode。当list、tuple、dict里面有中文时&#xff0c;打印出来的是Unicode编码&#xff0c;这个是无解的。对中文编码纠结的建议尽快…

实验三:进程管理编程实验

一【实验目的】 1.熟悉进程环境、进程生命周期&#xff1b; 2.支撑网络空间安全专业的专业核心能力、综合创新能力。 二【实验要求】 以下每个实验均要求&#xff1a; 1.“实验源代码”处&#xff1a;粘贴所编写的程序源码&#xff0c;务必添加关键语句的注释&#xff1b; 2…

会说话的狗狗本电脑版_会说话的电脑有点酷!惠普星14帮你解锁“偷懒”新姿势_惠普 星 14 2020(i5 1135G7/16GB/512GB/MX450)_笔记本新闻...

在现实生活中你是否遇到过这样的情况&#xff0c;笔记本近在咫尺&#xff0c;但你却懒得走到笔记本面前进行操作。当你疲惫地躺在床上时&#xff0c;心里也总是暗想&#xff0c;如果笔记本能够听我的指令跟我对话就好了。工作和生活当中&#xff0c;我们总免不了想要“偷懒”&a…