「Linux」进程等待与替换

在这里插入图片描述

💻文章目录

  • 📄前言
  • 进程等待
    • 进程等待的概念
    • 进程等待的方法
  • 进程替换
    • 进程替换的概念
    • 替换方式
  • 📓总结


📄前言

在如今的时代,多进程编程已经变成了必不可少的一部分,而进程等待、进程替换这两个概念都是作为多进程编程所必不可少的知识,为了掌握多进程编程,今天就从进程等待与替换开始吧。

进程等待

进程等待的概念

我们知道linux中进程拥有多种状态,例如僵尸状态、阻塞状态、运行状态等,而其中僵尸状态就是因为父进程没有接受到子进程的退出码而导致的状态,僵尸状态意味着系统无法对进程pcb的资源进行回收,过多的僵尸程序将导致系统内存泄漏、反应卡顿,严重时甚至会让系统挂死。所以,一个正常的多进程程序,父进程必须要接收完所有子进程的退出码,而这个接收的过程就是进程等待 <T_T。

进程等待的方法

进程等待的方式分为两种:

  • 阻塞等待:如同字面的意思,在等待子进程退出码的时候停止(阻塞)父进程的运行。
  • 非阻塞等待:在子进程运行的同时,父进程也运行代码,但是得不时对子进程的退出情况进行检查。

在C语言中,等待进程的函数为 waitwaitpid,它们的差别在与参数的不同。

#include<sys/types.h>
#include<sys/wait.h>

pid_t wait(int*status);
/*
返回值:
 成功返回被等待进程 pid,失败返回-1。
参数:
 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
*/

pid_ t waitpid(pid_t pid, int *status, int options);
/*
返回值:
	正常返回时返回子进程的pid,如果调用失败返回-1;
	注意:如果options设置成了非阻塞等待,子进程没有退出时返回0;
参数:
	pid:
 		Pid=-1,等待任一个子进程。与wait等效;
	 	Pid>0.等待其进程ID与pid相等的子进程;
 
 	status:
 		WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出);
 		WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码);
 
 	options:
 		WNOHANG: 若pid指定的子进程没有结束,程序返回0,父进程继续执行代码,在一段时间再次调用确定子进程退出;
*/
  • 阻塞等待
    阻塞等待意味着父进程在等待期间是什么都不做的,所以期间只有子进程在运行。
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
	pid_t id = fork();		//在linux系统中使用fork来生成子进程
	if(id < 0)
        _exit(1);	//子进程生成异常
	
	if(id == 0) //分流
	{	//子进程
        printf("child is run, pid is:%d\n",getpid());
        sleep(3);
        exit(0);
	}
	else
	{	//父进程
        int status = 0;
        pid_t ret = waitpid(-1, &status, 0);  //阻塞等待
        if(WIFEXITED(status) && ret == id)
            printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));
        else  
        {
            printf("wait child failed, return.\n");
            return 1;
        }
    }
	return 0;
}

在这里插入图片描述

  • 非阻塞等待
    非阻塞等待只需把 waitpid 最后的参数改为WNOHANG即可
int main()
{
	pid_t id = fork();		//在linux系统中使用fork来生成子进程
	if(id < 0)
        _exit(1);	//子进程生成异常
	
	if(id == 0) //分流
	{	//子进程
        printf("child is run, pid is:%d\n",getpid());
        sleep(3);
        exit(0);
	}
	else
	{	//父进程
        int status = 0;
        pid_t ret;
        do 
        {
            ret = waitpid(-1, &status, WNOHANG);  //非阻塞等待
            if (ret == 0)
            {
                printf("child is running\n");
            }
            sleep(1);
        }while (ret == 0);

        if(WIFEXITED(status) && ret == id)
            printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));
        else  
        {
            printf("wait child failed, return.\n");
            return 1;
        }
    }
	return 0;
}

在这里插入图片描述

进程替换

进程替换的概念

进程替代是指程序在运行期间执行另一个程序,但这个替换是把整个程序从头到尾都换成了新的程序(pcb还是同样的,所以进程id不变),即使替换的程序结束完毕,也不会回到原有的代码继续执行,所以一般都是由子进程来进行进程替换。

在这里插入图片描述

替换方式

C语言的进程替换函数

/*函数如果执行成功将会替换成新的程序,如果执行失败则返回-1*/
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

虽然函数很多,但其实它们都有着一套很好记得命名规范:

  • l (list):指使用列表参数,即可变参数列表(arg…)
  • v(vector):指使用使用数组来传递参数
  • p(path):指自动搜寻环境变量
  • e(env):指自己维护环境变量

在这里插入图片描述

替换实例

int main()
{
		pid_t id = fork();		
    if(id == 0)
    {	//子进程
        execlp("exa", "exa", "--icons", NULL);		//p代表自动搜索环境变量,无需使用绝对路径
        printf("child is exit\n");	//如果execlp执行成功不会打印
        exit(1);
    }
    else 
    {	//父进程
        printf("i'am father, pid:%d\n", getpid());
    }
	return 0;
}

在这里插入图片描述

📓总结

📜博客主页:主页
📫我的专栏:C++
📱我的github:github

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMvc集成开源流量监控、限流、熔断降级、负载保护组件Sentinel | 京东云技术团队

前言&#xff1a;作者查阅了Sentinel官网、51CTO、CSDN、码农家园、博客园等很多技术文章都没有很准确的springmvc集成Sentinel的示例&#xff0c;因此整理了本文&#xff0c;主要介绍SpringMvc集成Sentinel SpringMvc集成Sentinel 一、Sentinel 介绍 随着微服务的流行&…

git报错invalid object xxx和unable to read tree xxxxxx

电脑出问题了&#xff0c;导致git仓库像是被损坏了一样&#xff0c;执行git status就会报错unable to read ree&#xff0c;无法正常提交代码至仓库&#xff0c;原因是本地代码仓库.git文件损坏了&#xff0c;无法找到正确的提交历史和路径。 找到了一个解决办法&#xff1a; …

Android NDK项目配置CMake:一个CMakeList.txt配置多个子目录的源代码

文章目录 源码目录CMakeList.txt配置 分享一个项目的CMake配置&#xff0c;或许给你的项目配置提供参考&#xff1a; 源码目录 其中&#xff0c;除了include文件夹只包含头文件&#xff0c;其他文件夹都包含c文件和头文件&#xff1a; CMakeList.txt配置 # For more informa…

JavaScript中的异步处理方法

JavaScript中的异步处理是开发者在日常开发过程中必须面对的一个重要问题。由于JavaScript是单线程的&#xff0c;因此对于一些可能需要长时间执行的操作&#xff0c;如网络请求、IO操作等&#xff0c;如果采用同步的方式&#xff0c;可能会导致应用程序的阻塞&#xff0c;降低…

传感器:探索Android中的传感器功能与使用

传感器&#xff1a;探索Android中的传感器功能与使用 一、传感器介绍1.1 Android 平台三大类传感器1.2 Android 平台支持的传感器1.3 传感器框架 二、传感器的使用2.1 识别传感器和传感器特性2.2 针对不同制造商的传感器或传感器的不同版本优化2.3 监控传感器事件2.4 处理不同的…

什么是消息队列

什么是消息队列 MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出队列&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;M…

数据链路层之差错控制、奇偶校验码、CRC循环冗余码、海明码

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

【论文笔记】SDCL: Self-Distillation Contrastive Learning for Chinese Spell Checking

文章目录 论文信息Abstract1. Introduction2. Methodology2.1 The Main Model2.2 Contrastive Loss2.3 Implementation Details(Hyperparameters) 3. Experiments代码实现个人总结值得借鉴的地方 论文信息 论文地址&#xff1a;https://arxiv.org/pdf/2210.17168.pdf Abstrac…

金融行业CRM系统:有效跟踪客户数据,实现精准营销

今年市场经济下行&#xff0c;投资趋向于保守、人们消费降级&#xff0c;对于金融行业来说影响很大。受经济形式的影响加上行业的数字化转型升级&#xff0c;金融企业都在寻求客户管理的新策略&#xff0c;维护好忠实客户、吸引新客户投资。小编认为CRM系是管理客户的不二之选&…

不想花钱用aspera?这些免费的替代方案也同样快速哦

Aspera FASP是一款高速数据传输软件&#xff0c;被广泛应用于大文件的快速传输。然而&#xff0c;Aspera FASP并不便宜&#xff0c;对于一些小型企业或个人用户来说可能无法负担。因此&#xff0c;为了满足大家的需求&#xff0c;本文将介绍一些免费且同样快速的Aspera替代方案…

python之pyqt专栏8-信号与槽4

信号重载 在上一篇python之pyqt专栏7-信号与槽3-CSDN博客&#xff0c;我们知道在自定义信号时&#xff0c;可以设定信号参数数据类型。pyqt还支持信号重载。 信号定义 sendText pyqtSignal([int],[str]) 代码意思是定义重载信号sendText&#xff0c;槽函数的参数可以是int数…

【knife4j-spring-boot】Springboot + knife4j-spring-boot 整合swagger脚手架

swagger-boostrap-ui从1.x版本到如今2.x&#xff0c;同时也更改名字Knife4j 在此记录下 knife4j-spring-boot-starter 的整合。 只需要引入knife4j-spring-boot-starter&#xff0c;无需引入其他的swagger包&#xff0c;knife4j-spring-boot-starter已经包含。 官方版本说明…

ardupilot开发 --- ROS 篇

0. 前言 关于ROS/ROS2; 1. ROS/ROS2 1.1 概念碎片 LTS&#xff1a;long term support &#xff0c;一般指长期支持的版本&#xff1b;LTS 版本意味着更稳定&#xff0c;Latest 版本意味着键兼更多的platforms和拥有更新更多的ROS packages&#xff1b;尽管已经有了LTS版本&…

深入解析进程

在现代计算机系统中&#xff0c;进程是一个核心概念&#xff0c;它代表了程序的执行实例。通过并发执行多个进程&#xff0c;计算机能够提高效率和资源利用率。 1. 进程的概念 进程是指在计算机系统中正在执行的程序的实例。每个进程都有自己的地址空间、寄存器集合、堆栈和文…

java源码-数组

背景 上传图片&#xff0c;需要对图片格式进行校验&#xff0c;这是就可以使用数组 1、什么是数组&#xff1f; Java 语言中提供的数组是用来存储固定大小的同类型元素。 如&#xff1a;可以声明一个数组变量&#xff0c;如 numbers[100] 来代替直接声明 100 个独立变量 numb…

GoLong的学习之路,进阶,Redis

这个redis和上篇rabbitMQ一样&#xff0c;在之前我用Java从原理上进行了剖析&#xff0c;这里呢&#xff0c;我做项目的时候&#xff0c;也需要用到redis&#xff0c;所以这里也将去从怎么用的角度去写这篇文章。 文章目录 安装redis以及原理redis概念redis的应用场景有很多red…

第二证券:股票几点到几点开盘?

作为股民或许投资者&#xff0c;我们都知道股票是每天都有开盘和收盘时间的。但是&#xff0c;关于股票的开盘时间&#xff0c;很多人并不是很清楚&#xff0c;特别是初学者。在本文中&#xff0c;我们将从多个视点分析股票开盘时间&#xff0c;并为大家供给一些有用的信息。 …

深度学习毕设项目 基于深度学习的植物识别算法 - cnn opencv python

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 MobileNetV2网络4 损失函数softmax 交叉熵4.1 softmax函数4.2 交叉熵损失函数 5 优化器SGD6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&a…

科聪停车移动机器人整体解决方案!

停车机器人是用于在停车场或车库等场所中进行车辆的自动停放和取车操作。随着智能交通和智能城市的发展&#xff0c;停车机器人在解决停车难、提高停车效率和减少停车空间浪费等方面具有广阔的应用前景。 科聪停车机器人解决方案&#xff1a; 本方案中核心部分采用的是科聪通用…

kibana安装

kibana安装下载注意事项 地址&#xff1a;curl -O https://artifacts.elastic.co/downloads/kibana/kibana-7.16.3-linux-x86_64.tar.gz 下载后直接解压启动即可 1. 但需要使用非root用户启动 &#xff0c;root用户启动会报错 2. kibana需要和elasticsearch版本一致 不然…