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

【Linux系统】进程等待:告别僵尸进程深入理解Linux进程同步的核心密码

Linux系列


文章目录

  • Linux系列
  • 前言
  • 一、进程等待的核心目的
  • 二、进程等待的实现方式
    • 2.1 wait()函数
    • 2.2 waitpid()函数
  • 总结


前言

Linux系统中,进程等待(Process Waiting)是多进程编程中的核心机制,指父进程通过系统调用(如wait()、waitpid()等)主动等待子进程的结束,并回收其资源。


一、进程等待的核心目的

在进程状态篇,我给大家介绍了僵尸进程的问题。子进程执行结束后,如果父进程不及时处理子进程的状态信息,子进程就会进入僵尸状态,处于僵尸状态的进程无法通过信号杀死(如kill、ctrl+c),若父进程一直不对子进程结束信息处理,子进程的资源就无法得到释放,就会造成内存泄漏问题。

回收子进程资源

子进程退出后,内核会保留其退出状态和系统调用资源,直到等到父进程调用系统接口对子进程等待。如果不等待,子进程会变成僵尸进程,占用系统资源。

同步父子进程的信息

父进程创建子进程的目的就是让子进程执行一些任务的,有时父进程需要根据子进程的执行结果来决定后续的执行。

获取子进程状态

父进程通过wait()获取子进程的代码(成功/失败/异常),决定后续逻辑。

其实子进程的创建目的已经注定了父进程需要得到子进程的执行结果。

二、进程等待的实现方式

2.1 wait()函数


头文件
#include<sys/tyoes.h>
#include<sys/wait.h>
参数
整形指针,这个参数是一个输出型参数,目的是将函数内部信息带出(后面我们详细介绍)。
返回值
等待成功返回对应子进程的PID,失败则返回-1.

示例:

  1 #include<stdio.h>2 #include<sys/wait.h>3 #include<unistd.h>4 int main()5 {6   pid_t id=fork();7   if(id==0)8   {9     int cnt=5;10     while(cnt--)11     {12        printf("I am child,pid:%d,ppid%d\n",getpid(),getppid());13        sleep(1);  14     }  15   }  16   else  17   {  18     int cnt=10;  19     while(cnt--)  20     {  21       printf("I am parent process,pid:%d,ppid:%d\n",getpid(),getppid());                                                          22       sleep(1);  23     }  24    int status;25    pid_t ret= wait(&status);  26    if(ret==id)printf("父进程等待成功\n");27     sleep(20);28   }29   return 0;30 }

在这里插入图片描述

在这里插入图片描述
可以看到子进程结束后变为,僵尸状态当父进程对子进程等待成功后,子进程被释放,父进程继续自己的工作。

while :; do ps ajx|head -1&&ps ajx|grep test;sleep 1;echo "------------" ;done

接下来我们来介绍exit的参数:
在介绍进程等待原因时我们就说,父进程要获取子进程的退出状态信息,而这个获取方法就是通过status这个整形。

 31                  16 15       8 7        0
+---------------------+----------+----------+
|     保留位 (0)       | 信号编号  | 退出码   |
+---------------------+----------+----------+
|       高位           |   次高位   |   低位   |

在这个整形中0~7位存储的是进程退出码,8~15存储的是信号编号,要想知道终止信息,我们就需要对这个整形进行解析,当然我们可以通过位运算进行解析,不过库中给我们提供了两个用来解析的宏:

  • WIFEXITED(status):判断子进程是否正常退出(通过 exit()return)。
  • WEXITSTATUS(status):若子进程正常退出,提取其退出状态码(0~255)。
  1 #include<stdio.h>                                                                               2 #include<sys/wait.h>3 #include<unistd.h>4 #include<stdlib.h>5 int main()6 {7   pid_t id=fork();8   if(id==0)9   {10     int cnt=3;11     while(cnt--)12     {13        printf("I am child,pid:%d,ppid%d\n",getpid(),getppid());14        sleep(1);15     }16     exit(1);17   }18   else 19   {20     int cnt=5;21     while(cnt--)22     {23       printf("I am parent process,pid:%d,ppid:%d\n",getpid(),getppid());24       sleep(1);25     }26    int status;27    pid_t ret= wait(&status);                                                                    28    if(ret==id)29    {30      if(WIFEXITED(status))31      printf("父进程等待成功,并且子进程正常终止,退出码:%d\n",WEXITSTATUS(status));32    }33   return 0;34   }35 }

在这里插入图片描述
你也可以尝试使用信号杀死子进程。

2.2 waitpid()函数

在这里插入图片描述

头文件

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

参数

  1. pid:要等待进程的PID(如果父进程有多个子进程,我们可以指定等待,若为-1则同wait,随机等待)
  2. status:同wait
  3. options:控制等待行为(0为阻塞等待,WNOHANG为非阻塞轮询)。

返回值

成功时返回子进程的PID如果为,失败返回-1,如果第三个参数为WNOHANG未等待到返回0
先了解,后面会详细分析

在这里指定子进程PID访问不方便演示,大家可以自己创建多个子进程并查询某个子进程的PID,然后指定等待达到验证效果。

阻塞等待

在父进程等待子进程期间,父进进入阻塞状态,程序停止运行,直到等到子进程终止状态信息,父进程才会继续执行,在这期间父进程不会有任何行为。(这是给我自己看到->怎么等待呢?进入子进程PCB的等待队列,所以等待不一定等待是硬件资源

非阻塞轮询

父进程等待子进程时,不会进入阻塞状态,每隔一段时间程序就会看看waitpid是否完成对子进程的等待,如果没有完成,父进程就会利用空闲资源去做一些轻量级任务(如打印给网卡状态等)。

    1 #include<stdio.h>2 #include<sys/wait.h>3 #include<unistd.h>4 #include<stdlib.h>5 int main()6 {7   int status;8   pid_t id=fork();9   if(id==0)10   {11     int cnt=3;12     while(cnt--)13     {14        printf("I am child,pid:%d,ppid%d\n",getpid(),getppid());15        sleep(1);16     }17     sleep(10);18     exit(1);19   }20   else21   {                                                                                                                             22     pid_t ret;23     int cnt=5;24     while(cnt--)25     {26       ret= waitpid(0,&status,WNOHANG);27       if(ret==0)  28       printf("还没有等到子进程终止状态,再等等....\n"); //可在else语法块中执行轻量级任务,这里没展示                                                                          29       printf("I am parent process,pid:%d,ppid:%d\n",getpid(),getppid());  30       sleep(1);  31     }  32    if(ret==id&&WIFEXITED(status))  33    {  34      printf("父进程等待成功,并且子进程正常终止,退出码:%d\n",WEXITSTATUS(status));  35    }  36   }  37   return 0;  38 }  

在这里插入图片描述
这里还可以使用信号进行等待,到后面会给大家分享。

总结

进程等待是Linux多进程的基石,主要用来进行,资源等待、同步等待、I/O操作等待,进程等待是操作系统实现多进程并发执行和资源有效管理的重要手段,它使多个进程能够合理的共享资源,提高系统整体的性能和效率。

相关文章:

【Linux系统】进程等待:告别僵尸进程深入理解Linux进程同步的核心密码

Linux系列 文章目录 Linux系列前言一、进程等待的核心目的二、进程等待的实现方式2.1 wait()函数2.2 waitpid&#xff08;&#xff09;函数 总结 前言 在Linux系统中&#xff0c;进程等待&#xff08;Process Waiting&#xff09;是多进程编程中的核心机制&#xff0c;指父进程…...

根据文件名称查询文件所在位置

在 Linux 中&#xff0c;根据文件名称查询文件所在位置主要通过命令行工具实现&#xff0c;以下是几种常用方法&#xff1a; --- ### **1. 使用 find 命令&#xff08;最灵活&#xff09;** find 命令可以递归搜索指定目录下的文件&#xff0c;支持按名称、类型、时间等条件过…...

六十天前端强化训练之第二十五天之组件生命周期大师级详解(Vue3 Composition API 版)

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、生命周期核心知识 1.1 生命周期全景图 1.2 生命周期钩子详解 1.2.1 初始化阶段 1.2.2 挂载阶段 1.2.3 更新阶段 1.2.4 卸载阶段 1.3 生命周期执行顺序 1.4 父子组…...

Pytorch使用手册(专题五十)—自定义运算符

1. PyTorch 自定义运算符 PyTorch 提供了一个庞大的运算符库,这些运算符可以对张量进行操作(例如 torch.add、torch.sum 等)。然而,您可能希望向 PyTorch 引入一个新的自定义操作,并使其能够与诸如 torch.compile、autograd 和 torch.vmap 等子系统协同工作。为此,您必须…...

springboot整合mybatis-plus(保姆教学) 及搭建项目

一、Spring整合MyBatis (1)将MyBatis的DataSource交给Spring IoC容器创建并管理&#xff0c;使用第三方数据库连接池(Druid&#xff0c;C3P0等)代替MyBatis内置的数据库连接池 (2)将MyBatis的SqlSessionFactory交给Spring IoC容器创建并管理&#xff0c;使用spring-mybatis整…...

VSCode创建VUE项目(三)使用axios调用后台服务

1. 安装axios,执行命令 npm install axios 2. 在 main.ts 中引入并全局挂载 Axios 实例 修改后的 代码&#xff08;也可以单独建一个页面处理Axios相关信息等&#xff0c;然后全局进行挂载&#xff09; import { createApp } from vue import App from ./App.vue import rou…...

JVM常用垃圾回收器

Serial 和Serial Old收集器 Serial 系列的垃圾收集器采用了简单高效、资源消耗最少、单线程收集的设计思路。 简单高效&#xff1a;由于硬件资源有限&#xff0c;垃圾回收器需要设计得简单高效&#xff0c;以减少系统资源的占用。Serial 系列的垃圾收集器实现简单&#xff0c…...

车辆模型——运动学模型

文章目录 约束及系统移动机器人运动学模型&#xff08;Kinematic Model&#xff09;自行车模型含有加速度 a a a 的自行车模型系统偏差模型 在机器人的研究领域中&#xff0c;移动机器人的系统建模与分析是极为关键的基础环节&#xff0c;本文以非完整约束的轮式移动机器人为研…...

EJS缓存解决多页面相同闪动问题

基于 EJS 的模板引擎特性及其缓存机制&#xff0c;以下是关于缓存相同模块的详细解答&#xff1a; 一、EJS 缓存机制的核心能力 模板编译缓存 EJS 默认会将编译后的模板函数缓存在内存中&#xff0c;当相同模板文件被多次渲染时&#xff0c;会直接复用已编译的模板函数&#x…...

<details>和<summary>标签的用途,如何使用它们实现可折叠内容

大白话和标签的用途&#xff0c;如何使用它们实现可折叠内容 <details> 和 <summary> 标签用途 <details> 和 <summary> 标签是 HTML 里的实用标签&#xff0c;二者配合能创建出可折叠内容。 <details> 标签就像是一个容器&#xff0c;能把那…...

HUGO介绍、安装、以及使用

HUGO官方网站&#xff0c;文章内容的简介大部分来自官网的翻译&#xff0c;官网是纯英文描述&#xff0c;英语好的可以前往官方网站&#xff0c;博主在这里简介中简单翻译处理包括一些链接的引用&#xff0c;主要是讲解一下如何安装和使用。 这里再粘贴一个三方网站opendocs.i…...

【STM32实物】基于STM32的太阳能充电宝设计

基于STM32的太阳能充电宝设计 演示视频: 基于STM32的太阳能充电宝设计 硬件组成: 系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。 功能…...

【Netty】长连接与短连接的不同实现

长连接与短连接的不同实现 配置层面 // 长连接配置 bootstrap.option(ChannelOption.SO_KEEPALIVE, true) // 启用 TCP keepalive.option(ChannelOption.TCP_NODELAY, true); // 禁用 Nagle 算法// 短连接不需要这些配置心跳机制 // 长连接需要心跳 pipeline.addLast(new Idl…...

安装 OpenSSL 1.1.1 的完整脚本适用于 Ubuntu 22.04 系统

#!/bin/bash # 更新系统包 sudo apt-get update # 安装编译工具和依赖库 sudo apt-get install -y build-essential checkinstall zlib1g-dev # 下载 OpenSSL 1.1.1 源码 wget https://www.openssl.org/source/openssl-1.1.1.tar.gz # 检查下载是否成功 if [ $? -ne 0 ]; …...

24-智慧旅游系统(协同过滤算法)

介绍 技术&#xff1a; 基于 B/S 架构 SpringBootMySQLLayuivue 环境&#xff1a; Idea mysql maven jdk1.8 管理端功能 管理端主要用于对系统内的各类旅游资源进行管理&#xff0c;包括用户信息、旅游路线、车票、景点、酒店、美食、论坛等内容。具体功能如下&#xff1a; …...

Vue 中的日期格式化实践:从原生 Date 到可视化展示!!!

&#x1f4c5; Vue 中的日期格式化实践&#xff1a;从原生 Date 到可视化展示 &#x1f680; 在数据可视化场景中&#xff0c;日期时间的格式化显示是一个高频需求。本文将以一个邀请码关系树组件为例&#xff0c;深入解析 Vue 中日期格式化的 核心方法、性能优化 和 最佳实践…...

2025年使用Scrapy和Playwright解决网页抓取挑战的方案

0. 引言 随着互联网技术的发展&#xff0c;网页内容呈现方式越来越复杂&#xff0c;大量网站使用JavaScript动态渲染内容&#xff0c;这给传统的网络爬虫带来了巨大挑战。在2025年的网络爬虫领域&#xff0c;Scrapy和Playwright的结合为我们提供了一个强大的解决方案&#xff…...

可靠消息投递demo

以下是一个基于 Spring Boot RocketMQ 的完整分布式事务实战 Demo&#xff0c;包含事务消息、本地事务、自动重试、死信队列&#xff08;DLQ&#xff09; 等核心机制。代码已充分注释&#xff0c;可直接运行。 一、项目结构 src/main/java ├── com.example.rocketmq │ …...

阻止 Mac 在运行任务时进入休眠状态

掌握Caffeinate命令&#xff1a;让您的 Mac 保持清醒以完成关键任务 开发人员经常发现自己在 Mac 上运行持续时间较长的进程。无论是大量文件上传、广泛的数据分析脚本&#xff0c;还是复杂的构建过程&#xff0c;我们最不希望的就是我们的机器在任务中途进入睡眠状态。输入 c…...

Copilot提示词库用法:调整自己想要的,记住常用的,分享该共用的

不论你是 Microsoft 365 Copilot 的新用户还是熟练运用的老鸟&#xff0c;不论你是使用copilot chat&#xff0c;还是在office365中使用copilot&#xff0c;copilot提示词库都将帮助你充分使用copilot这一划时代的产品。它不仅可以帮助你记住日常工作中常用的prompt提示词&…...

Python实战(3)-数据库操作

前面说过&#xff0c;可用的SQL数据库引擎有很多&#xff0c;它们都有相应的Python模块。这些数据库引擎大都作为服务器程序运行&#xff0c;连安装都需要有管理员权限。为降低Python DB API的使用门槛&#xff0c;我选择了一个名为SQLite的小型数据库引擎。它不需要作为独立的…...

LeetCode 160 Intersection Of Two Linked Lists 相交链表 Java

题目&#xff1a;找到两个相交列表的起始点&#xff0c;如图c1开始为A和B两个链表的相交点 举例1&#xff1a;8为两个链表的相交点。 注意&#xff1a;相交不止是数值上的相同。 举例2&#xff1a;2为相交点 举例3&#xff1a;没有相交点 解题思路&#xff1a; 相交证明最后一…...

AI Agent中的MCP详解

一、协议定义与核心价值 MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的开放标准协议,其核心目标是通过建立统一接口规范,解决AI模型与外部系统集成效率低下的行业痛点。该协议通过标准化通信机制,使大型语言模型(LLM)能够无缝对接数…...

win系统上自动化安装配置WSL linux和各种生信工具教程

windows系统上自动化安装配置WSL linux系统和各种生信工具教程 高通量测序原始数据的上游分析模块介绍 我开发的OmicsTools软件的这些分析测序原始数据的上游处理分析模块需要使用到linux和linux系统中的一些生信工具&#xff0c;在这里我开发了在windows系统中自动化安装WSL …...

统计可重复列表中的TOP N

文章目录 方案1&#xff1a;HashMap统计 全排序实现步骤&#xff1a;代码实现&#xff1a;优缺点&#xff1a; 方案2&#xff1a;HashMap统计 最小堆&#xff08;优先队列&#xff09;实现步骤&#xff1a;代码实现&#xff1a;优缺点&#xff1a; 方案3&#xff1a;Java Str…...

PowerBI纯小白如何驾驭DAX公式一键生成:copilot for fabric

在2025年2月份更新中&#xff0c;powerbi desktop里的copilot功能还新增了一个非常强大的功能&#xff1a;一键生成多个度量值&#xff0c;并直接加载到模型。 直接上示例展示&#xff1a; 打开DAX查询视图&#xff0c;在copilot窗格中直接输入想要生成多个度量值&#xff0c…...

Pytest的夹具

1、pytest的前置后置夹具 fixture 有些内容是在每个用例执行之前都要运行操作:-- 用例前置 接口:购物车模块先登录 --登录结果 【token鉴权】 UI: 每次用例 打开浏览器 --driver 有些内容在每个用例之后都要运行操作:–用例后置 接口: 数据清除 UI:关闭浏览器 叫做用例的…...

两市总的净流出和净流入来分析情况

为了排查数据干扰&#xff0c;只从两市总的净流出和净流入来分析情况。 净流出才对应资金抽离&#xff1a;若净流入为负&#xff08;即净流出&#xff09;&#xff0c;则意味着资金从股市中撤出&#xff0c;例如主动卖出的金额超过主动买入金额。净流入反映市场信心&#xff1…...

GitHub在push推送到远程仓库的时候显示Logon failed登录失败

具体问题描述 git.exe push --progress "origin" master:master Logon failed, use ctrlc to cancel basic credential prompt. remote: Support for password authentication was removed on August 13, 2021. 这是因为Git 推送失败的原因是 GitHub 已经不支持密码认…...

如何在SQL中高效使用聚合函数、日期函数和字符串函数:实用技巧与案例解析

文章目录 聚合函数group by子句的使用实战OJ日期函数字符串函数数学函数其它函数 聚合函数 函数说明COUNT([DISTINCT] expr)返回查询到的数据的 数量SUM([DISTINCT] expr)返回查询到的数据的 总和&#xff0c;不是数字没有意义AVG([DISTINCT] expr)返回查询到的数据的 平均值&…...