进程、孤儿进程、僵尸进程、fork、wait简介

 进程相关概念

        程序和进程
程序:是指编译好的二进制文件,在磁盘上,占用磁盘空间, 是一个静态的概念.
进程:一个启动的程序, 进程占用的是系统资源,如:物理内存,CPU,终端等,是一个动态的概念

进程状态

        进程基本的状态有5种。分别为初始态,就绪态,运行态,挂起态与终止态。其中初始态为进程准备阶段。

PCB:进程控制块

        进程控制块(Process Control Block,PCB)是操作系统中用于管理和控制进程的重要数据结构。每当操作系统创建一个新进程时,它会为该进程分配一个 PCB,其中包含了与该进程相关的所有信息。Linux内核的进程控制块是task_struct结构体。
       
        vim /usr/src/linux-headers-6.8.0-45/include/linux/sched.h  #6.8.0-45linux版本替换成自己的电脑上的版本   进入这个文件可以查看task_struct结构体的定义。

        task_struct结构体内部成员有很多,我们重点掌握以下部分即可:
进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。
进程的状态,有就绪、运行、挂起、停止等状态。
描述虚拟地址空间的信息。
进程切换时需要保存和恢复的一些CPU寄存器。
文件描述符表,包含很多指向file结构体的指针。
用户id和组id。
进程可以使用的资源上限(Resource Limit):使用ulimit -a 命令可以查看

并行和并发

        并发,在一个时间段内, 是在同一个cpu上, 同时运行多个程序。
        如:若将CPU的1S的时间分成100个时间片,每个进程执行完一个时间片必须无条件让出CPU的使用权,这样1S中就可以执行100个进程。高并发可以简单理解为是在有限时间内,系统能够处理尽可能多的进程或请求。
        并行指两个或两个以上的程序在同一时刻发生(需要有多颗cpu,现在我们电脑的cpu都是多核)。就是说,有多个cpu上同时运行着不同程序。

孤儿进程

        孤儿进程的概念:若子进程的父进程已经终止,而子进程还在运行,这个进程就成了孤儿进程。
        为了保证每个进程都有一个父进程,孤儿进程会被init进程(
进程标识符(PID)为1)领养,init进程成为了孤儿进程的养父进程,当孤儿进程退出之后,由init进程完成对孤儿进程的回收。

僵尸进程

        僵尸进程的概念:若子进程终止,父进程还在运行, 但是父进程没有调用wait或waitpid函数完成对子进程的回收,则该子进程就成了僵尸进程。
        
如何解决僵尸进程?
        由于僵尸进程是一个已经终止的进程,所以不能使用kill命令将其杀死

        通过kill其父进程的方法可以消除僵尸进程。

终止掉其父进程后,这个僵尸进程会被init进程领养,由init进程完成对僵尸进程的回收。

fork函数

        函数作用:创建子进程
原型: pid_t fork(void);
使用时需要包含头文件:#include <unistd.h>
函数参数:无
返回值:调用成功:父进程返回子进程的PID,是一个大于0的数;
              子进程返回0。
注意:不是fork函数在一个进程中返回两个值,而是在父子进程各自返回一个值。
fork函数原理图:(PCB在上边有介绍)

子进程创建成功后,代码的执行位置?
        
进程会从 fork() 调用后的下一行代码开始继续执行。这意味着,在 fork() 后面有条件判断或逻辑分支,可以通过检查 fork() 的返回值来确定当前是在父进程还是在子进程中。
如何区分父子进程?
        
通过fork函数的返回值
父子进程的执行顺序?
        
不一定,哪个进程先抢到CPU,哪个进程就先执行。
fork函数代码简单实例:调用fork函数创建子进程,分别打印出子进程pid和父进程pid等。代码里用到了getpid和getppid函数,比较简单,这里不在介绍。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int main(void)
{
	printf("before fork,pid[%d]\n",getpid());
	pid_t pid = fork();
	printf("test\n");
	if(pid<0)
	{
		perror("fork error");
		return -1;
	}
	else if(pid>0)
	{
		printf("father:[%d],pid =[%d],fpid=[%d]\n",pid,getpid(),getppid());
	}
	else if(pid==0)
	{	
		printf("child:pid =[%d],fpid=[%d]\n",getpid(),getppid());
	}
	printf("after fork,pid:[%d]\n",getpid());

	return 0;

}

运行结果如下:

其次,父子进程对某个变量进行修改时需要注意,父进程若修改某个变量的值,子进程中这个变量的值不会改变,试想,如果子进程中某个变量的值能跟随父进程中对应变量的值进行变化,就相当于进行了父子间进程通信!显然,在这份代码中并没有做到。
 

//fork函数测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/wait.h>

int test = 6;

int main()
{
	//创建子进程
	pid_t pid = fork();
	if(pid<0) //fork失败的情况
	{
		perror("fork error");
		return -1;
	}
	else if(pid>0)//父进程
	{
		printf("parent: [%d], pid=[%d], fpid=[%d]\n", pid, getpid(),getppid());
		test += 2;
		printf("parent:[%p]\n", &test);
		printf("parent: test==[%d]\n",test);
        //wait(NULL);
	}
	else if(pid==0) //子进程
	{
		sleep(2); //为了避免父进程还没有执行, 子进程已经结束了
		printf("[%p]\n", &test);
		printf("child: pid==[%d], fpid==[%d]\n", getpid(), getppid());
		printf("child: test==[%d]\n", test);
	}
	
	return 0;
}

执行结果:这里父进程结束后,子进程的fpid是1(init进程的pid为1),这个进程(就是孤儿进程最上边有解释)会被init进程领养,由init进程完成对孤儿进程的回收。但是执行完并没有自动退出终端,如果想让其自动退出终端,把上述代码的wait注释去掉。

wait函数

        pid_t wait(int *_Nullable wstatus);
函数作用:阻塞并等待子进程退出、回收子进程残留资源、获取子进程结束状态(退出原因)。

返回值:
        成功:清理掉的子进程ID;
        失败:-1 (没有子进程
);

wstatus参数:子进程的退出状态 --
传出参数

  • WIFEXITED(wstatus):为非0        → 进程正常结束
  • WEXITSTATUS(wstatus):获取进程退出状态
  • WIFSIGNALED(wstatus):为非0 → 进程异常终止
  • WTERMSIG(status):取得进程终止的信号编号。
    wait函数实例:实现父进程调用wait函数完成对子进程的回收
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main()
    {
    	//创建子进程
    	pid_t pid = fork();
    	if(pid<0) //fork失败的情况
    	{
    		perror("fork error");
    		return -1;
    	}
    	else if(pid>0)//父进程
    	{
    		printf("father: [%d], pid==[%d], fpid==[%d]\n", pid, getpid(),getppid());
    		int wstatus;
    		pid_t wpid = wait(&wstatus);
    		printf("wpid==[%d]\n", wpid);
    		if(WIFEXITED(wstatus)) //正常退出
    		{
    			printf("child normal exit, wstatus==[%d]\n", WEXITSTATUS(wstatus));
    		}
    		else if(WIFSIGNALED(wstatus)) //被信号杀死
    		{
    			printf("child killed by signal, signo==[%d]\n", WTERMSIG(wstatus));
    		}
    		
    	}
    	else if(pid==0) //子进程
    	{
    		
    		printf("child: pid==[%d], fpid==[%d]\n", getpid(), getppid());
    		sleep(10);
    		return 9;
    	}
    
    	return 0;
    }
    

    结果:

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

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

相关文章

【万兴科技-注册_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【笔记】数据结构与算法

参考链接&#xff1a;数据结构(全) 参考链接&#xff1a;数据结构与算法学习笔记 一些PPT的整理&#xff0c;思路很不错&#xff0c;主要是理解角度吧&#xff0c;自己干啃书的时候结合一下会比较不错 0.总论 1.数据 注&#xff1a;图是一种数据结构&#xff01;&#xff01;…

匿名内部类的理解

这个知识点困惑我很久&#xff0c;前几天面试的时候也问到了&#xff0c;没回答出来 首先先说说使用步骤吧 1.有一个接口&#xff0c;且含有一个抽象方法&#xff08;通常情况我们不会写abstract关键字&#xff0c;冗余的&#xff09; 2.然后有一个外部类&#xff08;Anonymo…

深入探索电能消耗数据:基于机器学习的分析与洞察

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

架构的本质之 MVC 架构

前言 程序员习惯的编程方式就是三步曲。 所以&#xff0c;为了不至于让一个类撑到爆&#x1f4a5;&#xff0c;需要把黄色的对象、绿色的方法、红色的接口&#xff0c;都分配到不同的包结构下。这就是你编码人生中所接触到的第一个解耦操作。 分层框架 MVC 是一种非常常见且常…

突破挑战,创新前行 | 生信科技SOLIDWORKS 2025新品发布会·合肥站精彩回顾

2024年10月18日&#xff0c;由生信科技举办的首场SOLIDWORKS 2025新产品发布会在安徽合肥圆满落幕。现场邀请到制造业的专家学者们一同感受SOLIDWORKS 2025最新功能&#xff0c;探索制造业数字化转型之路。 合肥站活动日&#xff0c;由生信科技副总经理徐建开场。他以智造无界&…

鸿蒙HarmonyOS应用开发者(基础+高级)认证

文章目录 鸿蒙HarmonyOS应用开发者(基础高级)认证&#x1f449;1.HarmonyOS认证介绍1.1、HarmonyOS发展历程1.2、HarmonyOS NEXT 开发预览版1.3、ArkTS语言开发鸿蒙应用1.4、HarmonyOS应用开发者基础认证的核心内容1.5、HarmonyOS应用开发者高级认证的核心内容1.6、HarmonyOS应…

三菱变频器A800\F800\D700E700\CS80等系列变频器选件一览

配备了丰富的选配件&#xff0c;可以提升变频器的性能、增加功能、支持更多的安装方式等。 变频器和外围设备 选件表

精准提炼 | SOLIDWORKS 2025:工程图与钣金焊件新功能

SOLIDWORKS 每年的更新都致力于提升用户的设计效率与体验&#xff0c;SOLIDWORKS 2025 同样带来了众多改进&#xff0c;下面让我们快速了解一下在SOLIDWORKS 2025 工程图与钣金焊件方面的新功能。 工程图相关 一、表面粗糙度符号标注 新版本现在将符合更新 ISO 标准 (ISO 21…

SpringBoot核心框架之AOP详解

SpringBoot核心框架之AOP详解 一、AOP基础 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程&#xff0c;面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 场景&#xff1a;项目部分功能运行较慢&#xff0c;定位执行耗时…

【万户软件-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

HBuilder X 中Vue.js基础使用4->表单输入绑定(三)

表单绑定是实现动态数据双向绑定的重要部分&#xff0c;它让开发者可以轻松地管理和响应用户输入。本文将详细介绍如何在Vue 3中利用v-model指令以及一些特定修饰符来处理不同类型的表单输入。 v-model双向数据绑定 Vue的 v-model 指令提供了双向绑定的功能&#xff0c;key在…

动态规划-回文串问题——647.回文子串

1.题目解析 题目解析&#xff1a;647.回文子串——力扣 测试用例 2.算法原理 1.状态表示 本题需要判断一段字符串是否为回文子串&#xff0c;因此最简单的方法就是保存起开始位置与结束位置&#xff0c;那么就需要一个二维的dp表来保存一段字符串是否为回文子串&#xff0c;…

AI绘画王者归来!SD恐怖如斯!Facebook最强人体分割大师Sapiens 吊打SAM2,亦可Pose,Depth,Normal,ComfyUI

在AI绘画领域&#xff0c;SD恐怖如斯和Facebook的Sapiens模型一直是业界关注的焦点。而最近&#xff0c;Sapiens模型凭借其强大的人体分割能力&#xff0c;再次成为AI绘画领域的佼佼者。 SD恐怖如斯和Sapiens模型的优势 SD恐怖如斯是一款基于深度学习的AI绘画模型&#xff0c;…

Redis-06 Redis复制

主&#xff1a; 192.168.248.132 6379 从1&#xff1a; 192.168.248.140 6380 从2&#xff1a; 192.168.248.139 6381 1.三大命令 拷贝一个新的redis.conf&#xff08;出厂默认&#xff0c;没修改的&#xff09;的文件 2.配置详情 2.1 改为yes 2.2 87行注释掉 2.3 改为no …

什么是成品系统源码,哪里有成品源码,成品源码二次开发需要多久?

成品系统源码指的是已经开发完成、可以立即部署或根据需求进行二次开发的软件系统源代码。这些源码通常包括但医疗信息化软件&#xff08;如HIS、LIS、PACS等&#xff09;、智慧工地源码、家政预约上门系统、实验室管理系统、定位系统源码以及生产管理系统等。 1、医疗信息化软…

[OceanBase-不止于记录]:揭秘双引擎战略,共探AI时代数据架构未来

前言 又到了一年一度大家最爱的探会文章&#xff0c;非常荣幸收到OceanBase官方的邀请参加2024 OceanBase 年度发布会&#xff0c;作为一个经常参加线下探会的博主&#xff0c;每一次体验都有所不同&#xff0c;每一次新技术的突破都让人感到无比兴奋。同时&#xff0c;作为数…

ELK之路第三步——日志收集筛选logstash和filebeat

logstash和filebeat&#xff08;偷懒版&#xff09; 前言logstash1.下载2.修改配置文件3.测试启动4.文件启动 filebeat1.下载2.配置3.启动 前言 上一篇&#xff0c;我们说到了可视化界面Kibana的安装&#xff0c;这一篇&#xff0c;会简单介绍logstash和filebeat的安装和配置。…

终于完工! ffmpeg 视频滤镜:添加文本-drawtext

滤镜描述 drawtext 官网链接 》 FFmpeg Filters Documentation 这个滤镜可以给视频添加上文本&#xff0c;可以给文本加边框、颜色、阴影。注意不是字幕功能&#xff0c;因为这个滤镜不能精准的控制开始和结束的时间。 滤镜使用 参数 fontfile <string> …

【模型学习之路】手写+分析Transformer

手写分析transformer 目录 前言 positional encoding 注意力机制 多头注意力 高维度乘法 多头注意力机制 多头注意力层的实现 Encoder FeedForwardNet EncoderLayer Encoder Decoder DecoderLayer Decoder 组装Trasformer! 后话 测试一下 mask 前言 Attenti…