Linux fork子进程,进程退出与等待

【Linux】进程创建(fork函数)及其等待与退出 进程创建 进程是把该程序运行起来加载到内存,受OS控制,建立PCB,OS把PCB管理好就是把进程管理好。 以fork为例: fork函数 在Linux中fork函数是非常重要的函数,会创建子进程,原进程是父进程。 子进程返回0,父进程返回子进程id。 进程调用fork,当控制转移到内核中的fork代码后,内核做以下动作: 分配新的内存块和内核数据给子进程; 将父进程部分数据结构内容拷贝至子进程;... 阅读详情

title:
date: 2024-07-07 12:57:17
tags: fork Linux
cover: https://picbed0521.oss-cn-shanghai.aliyuncs.com/blogpic/PixPin_2024-07-25_22-26-59.png


原文见我的网站: www.supdriver.top

认识fork()

头文件<unistd.h>提供的fork()函数用于从已有的原进程创建一个新的子进程,而原进程在关系式称为父进程

fork()的返回值

#include <unistd.h>
pid_t id = fork();

父子进程中fork()函数的返回值(此处用变量id储存)是不同的:

父进程里id的值为子进程的PID,其值>0;子进程里id值固定为0

  • id > 0 父进程
  • id == 0 子进程
  • id < 0 fork()失败

分流

利用父子进程中fork()返回值的不同,可以用if...else...进行分流,让父子进程执行不同的代码

fork()的过程

进程调用fork,当控制转移到内核中的fork代码后,内核做

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

当一个进程调用fork之后,就有一对二进制代码相同的父子进程。而且它们都运行到相同的地方。但每个进程都可以独立地继续运行代码,并按代码分流至不同的代码段

但这两个进程谁先执行完全由调度器决定,而谁先结束,则由实际执行情况和调度器决定

拷贝的过程 与 写时拷贝

fork时,子进程会将父进程虚拟内存的内容都复制一份在自己的虚拟内存中,但通过页表,二者映射到了同一块物理内存的区域,这样在二者都没有写入行为时,减少了物理内存中冗余的拷贝行为,有效提高了运行效率

但当父子进程中有一方发生写入行为时,就会触发写时拷贝,此时物理内存中发生拷贝行为,但只拷贝进程映射的数据段,而由于不发生进程替换时父子进程的代码段一定相同,物理内存中,代码段映射部分并不发生拷贝

进程退出

进程退出的场景

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止

进程常见退出方法

  • main函数返回
  • exit退出
  • _exit退出

异常退出: ctrl + c

查看退出码

在终端使用命令echo $?可以查看退出码

注尽管子进程返回的是int,父进程只取退出码的最低8位,所以以下三种情况

  • main函数返回-1
  • exit(-1)
  • _exit(-1)

在终端输echo $?可得退出码255

exit 和 _eixt 辨析

main函数返回就不惜说了,来辨析一下头文件<stdlib.h>提供的exit和_exit函数

_exit()

_exit会直接终止进程并返回状态码,而不会执行用户定义的清理函数,也不会清理缓冲区

exit()

exit实际上最后也会调用_exit,但它会先执行一系列善后工作,顺序如下:

  1. 执行用户通过 atexit或on_exit定义的清理函数。
  2. 关闭所有打开的流,所有的缓存数据均被写入
  3. 调用_exit

return退出: 执行return n等同于执行exit(n)

进程等待

进程等待的必要性

  • 子进程退出后需要父进程来回收僵尸进程,防止产生其引发内存泄漏等问题
  • 僵尸进程难以处理,kill -9也清理不掉
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

进程等待的方法

wait方法

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

pid_t wait(int*status);

参数:显然status是输出型参数,获取子进程的退出状态,若不关心,可传参NULL

返回值: 若成功,则返回被等待进程的pid,若失败,则返回-1

waitpid方法

返回值:
当正常返回的时候waitpid返回收集到的子进程的进程ID;
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

参数:
pid:
pid == -1,等待任一个子进程。与wait等效。
pid > 0.等待其进程ID与pid相等的子进程。
status:
输出型参数传参&status: 将子进程的状态码存入status
以下两个宏函数用于处理状态码:
WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
options:
WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
0: 阻塞等待指定pid的进程

阻塞等待

option == 0时waitpid采用阻塞等待,父进程会阻塞等待到子进程退出

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
    int status;
    pid_t id = fork();
    if(id == 0)
    {
        for(int i = 1;i<=5;i++)
        {
            printf("child running [%d]s\n",i);
            sleep(1);
        }
        printf("child exited\n");
        exit(0);
    }
    else
    {
        waitpid(id,&status,0);
        if(WIFEXITED(status))
            printf("father wait success, exit code: %d\n",WEXITSTATUS(status));
        else
            printf("child failed to exit\n");
    }
    return 1;
}
非阻塞轮询

option == WNOHANG时,waitpid采用非阻塞等待,若等不到子进程退出,就会继续执行后面的代码,所以一般加上while等循环用于轮询,二者共同构成非阻塞轮询

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

//非阻塞轮询
int main()
{
    int status;
    pid_t id = fork();
    if(id == 0)
    {
        sleep(5);
        printf("child exited\n");
        exit(0);
    }
    else
    {
        while(1)//轮询
        {
            pid_t rid = waitpid(id,&status,WNOHANG);
            if(rid > 0)
            {
                if(WIFEXITED(status))
                    printf("father wait success, exit code: %d\n",WEXITSTATUS(status));
                else
                    printf("child failed to exit\n");

                break;
            }
            else if(rid == 0)
            {
                printf("等待子进程中...\n");
                sleep(1);
            }
            else//rid<0
            {
                printf("wait failed\n");
                break;
            }
        }
    }
    return 1;
}
逆变器专题(9)-基于dq坐标系的逆变器解耦控制建模与实时仿真分析 本文深入探讨了基于dq坐标系的逆变器解耦控制建模与实时仿真分析。通过生动的比喻和详细的数学推导,阐述了如何通过坐标变换和前馈补偿实现d轴与q轴的独立控制,从而提升系统动态性能与稳定性。文章还介绍了在MATLAB/Simulink中搭建仿真模型、分析动态响应与稳定性的方法,并展望了硬件在环(HIL)实时仿真的高级验证手段,为新能源并网与电机驱动领域的工程师提供了宝贵的实践指南。 阅读详情

相关推荐

P450酶催化循环的Amber-Gromacs混合模拟实战:从血红素加氧到产物释放

本文详细介绍了针对P450酶完整催化循环的Amber-Gromacs混合模拟实战策略。通过Amber为关键氧合血红素中间体(CPDI)构建精确力场,再利用Gromacs的高效GPU加速进行长时间尺度动力学模拟,完整覆盖从底物结合到产物释放的催化过程,为研究酶催化机制提供了强大的计算工具。

weixin_29201859的博客 315

进程(二)—— fork()创建子进程

上一次说明了进程是怎么被创建的,进程的程序又是如何运行的,本文主要介绍fork()函数创建进程的过程中发生了什么,结合代码进行过程分析

challenglistic的博客 1万+

PostgreSQL14 离线安装全攻略:从下载到配置详解

本文详细介绍了PostgreSQL14在无网络环境下的离线安装全流程,涵盖RPM包与源码编译两种主流方法。文章重点解析了安装前的系统环境检查、依赖包准备、数据库初始化、远程访问配置以及安装后的关键检查与性能调优,旨在帮助运维和开发人员在离线服务器上高效、稳定地部署PostgreSQL14数据库。

p5l2m9n4o6q的博客 719

fork子进程

一、相关函数 fork函数:创建一个新的进程,当前进程是新进程的父进程 通过man 2 fork命令可以查看linux手册中第二节关于fork函数的介绍 #include <unistd.h> pid_t fork(void); fork函数返回值类型是pid_t ,本质就是一个int类型的值,它有3中可能的返回结果: -1:创建失败,在父进程中返回-1 0:创建成功,当前进程是子进程 其他:创建成功,在父进程中返回子进程的pid(进程 ID) linux系统还提供了一些函数,用来获

start_mao的博客 4175

AD2S1210与DSP28335 SPI通信中的GPIO配置陷阱与解决

本文深入剖析了AD2S1210与DSP28335进行SPI通信时,因GPIO输入限定配置不当导致数据整体右移的典型问题。文章指出,错误地将MISO引脚配置为带采样周期的同步模式是根本原因,并提供了将输入选择限制正确设置为异步模式的解决方案。同时,总结了不同应用场景下GPIO输入限定的配置原则,为高速同步通信的稳定实现提供了关键指导。

weixin_29163857的博客 146

【脚本篇】---spyglass lint脚本

【代码】【脚本篇】---spyglass lint脚本。

冬瓜 6357

fork创建子进程详解

本文详解了fork,解决了关于fork的几个难点

adcxhw的博客 2713

【YOLOv8/v9/v10 实战 01】YOLOv8/v9/v10全系列实战对决:性能矩阵、架构拆解与2026部署指南

2026年YOLO生态已进入“战国时代”,Ultralytics YOLOv8/11/26、阿里YOLO12、清华YOLOv10、微软YOLOv9四大路线并行发展。本文基于官方文档、学术论文及实测数据,系统剖析三大核心版本(YOLOv8/v9/v10)的架构演进逻辑,构建覆盖参数量、mAP、FPS、FLOPs的完整性能矩阵。通过8组工业场景实测、全流程代码实现(训练-导出-部署)、6类硬件适配方案,解决新手选型难、进阶者优化无门、工业开发者部署低效的痛点。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 534

[入门篇]Linux操作系统fork子进程的创建以及进程的状态 超超超详解!!!我不允许有人错过!!!

0.前言1.fork()创建子进程讲解1.1fork()的简单介绍1.2 创建子进程详解1.2.1 如何理解fork创建子进程1.2.2 子进程的PCB以及子进程的代码和数据1.2.3为什么要共享&&写时拷贝1.2.4 什么时候发生写时拷贝1.3 fork函数返回值详解1.3.1引入fork返回值的作用1.3.2 fork返回执行逻辑剖析1.3.3 小问题补充2.进程状态2.1 进程状态引入2.2 初识进程中的状态2.3 R状态解析2.4 S状态解析2.4.1 S状态的具体表现2.4.2 CPU视角下的进程

qq_63992711的博客 9339

22、光无线通信调制技术详解

本文详细介绍了光无线通信中的多种调制技术,包括开关键控(OOK)、脉冲位置调制(PPM)、数字脉冲间隔调制(DPIM)、副载波强度调制(SCM)、相移键控(PSK)、正交幅度调制(QAM)以及多载波调制(MCM)如OFDM和MSIM。文章分析了各类调制技术在带宽需求、功率效率、传输容量、传输速率和PAPR等方面的性能差异,并通过Matlab仿真展示了其在AWGN信道下的误码率表现。同时,对比了不同技术的适用场景,提出了调制选择流程,并结合室内光通信与自由空间光通信的应用案例,展望了未来调制技术向高频谱效率、

net55的博客 116

Python爬虫selenium验证-中文识别点选+图片验证码案例

环境对模型进行训练,参考:https://github.com/sml2h3/dddd_trainer。能识别,但是发现默认识别率有点低,想要提升识别率,可以搭建。截图每个字符,并基于ddddocr识别。根据坐标,在验证码上进行点击。

dme.的博客 2165

fork函数创建子进程&僵尸进程&孤儿进程详讲

1、创建子进程 1.1 fork() 首先他是一个系统调用函数 作用:谁调用fork函数,调用成功之后,谁就创建出来一个子进程。 1.2fork()的返回值 创建成功: fork会返回两次在父进程中返回一次,在创建的子进程中返回一次。 >0返回给父进程(返回子进程的pid) ==0返回给子进程 创建失败: 返回-1 1.3、fork的原理 子进程拷贝父进程的PCB 父子进程代码共享(父子进...

weixin_45897952的博客 3361

【YOLO26保姆级零踩坑教程】环境搭建+五大任务快速入门,一行代码实现检测/分割/姿态/OBB/分类(Win+Linux全适配)

YOLO26环境搭建与实战指南:零踩坑全适配 本文是YOLO26全栈技术专栏的入门篇,提供Windows/Linux双系统的纯实战环境搭建指南,主打零踩坑、全适配。YOLO26基于Ultralytics框架优化,无需编译源码或手动下载权重,原生支持多任务推理。 环境配置关键点: 必须安装Ultralytics 8.4.0及以上版本 支持CPU/GPU环境,推荐Python 3.8-3.11 提供清华源配置解决下载慢问题 安装步骤: CPU版:一键安装Ultralytics和OpenCV GPU版:匹配CUD

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 774

【Linux】进程控制(1)(进程创建 写时拷贝 fork常见用法 fork调用失败的原因 进程终止 退出码 进程退出的情况 进程等待 进程等待的必要性 进程等待的方法 获取子进程的退出信息)

我们使用创建子进程的方式调用fork,创建子进程,子进程跑10s,10s后退出,然后父进程会等15s,在前10s,子进程一定会退,退了之后,没有人等他没有人wait他,所以子进程处于Z状态,大概再等5s钟,父进程休眠完了,醒来调用wait的时候,此时wait会去回收子进程,回收子进程就会将子进程的状态从Z释放了,我们就能看到,开始是两个进程,后来变成一个进程是S或者R,另一个是Z,再过上5s钟,发现只有一个父进程了。有两个空间,一个是用户空间,写我们自己的代码,另一个是内核空间,里面是操作系统的代码。

m0_68800221的博客 951

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【Linux系统编程之进程】创建进程,父进程等待子进程退出,fork,vfork,exec族函数等

什么是程序,什么是进程,进程标识符,什么叫父进程,什么叫子进程?,fork函数创建,vfork创建,父进程等待子进程退出,什么是僵尸进程,wait函数,waitpid函数,孤儿进程,exec族函数,system函数,oppen函数,使用 ps 命令,如 ps -aux 查看所有进程的详细信息。 - 使用 top 或 htop 命令实时监控系统的进程。 - 使用 pstree 命令以树形结构显示进程。

qq_40064717的博客 1250

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Linux进程—vfork函数的使用,父进程等待子进程退出,vfork和fork区别

Linux进程—vfork函数的使用,父进程等待子进程退出,vfork和fork区别

嵌入式小白 记录学习过程 556

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【Linux 进程控制】—— 进程亦生生不息:起于鸿蒙,守若空谷,归于太虚

在技术的世界里,进程的生死流转恰似东方哲学中的一场静默修行——它们悄然诞生于系统的混沌,在等待中沉淀为时间的艺术,最终化作虚无回归万物本源。这篇博客将冷峻的代码逻辑浸润于华夏文明的深邃长河。透过道家“无中生有”的宇宙观,你会看到 fork 的创世之力如鸿蒙初辟;在阻塞与非阻塞的等待中,听见空谷回响般的调度禅机;而进程的终止,则是一场向“太虚”的优雅谢幕。此文能为你揭开进程的另一重维度——那里,硅基的精密与东方的哲思,正悄然共鸣。

bite_zwy的博客 1万+

控制欲过强的Linux小进程

控制欲强?视奸?普通人那才叫视奸,您是皇帝,天下大事无一逃过您的耳目,您想看什么就看什么,臣怀疑他在朋友圈私养兵士,囤积枪甲,蓄意谋反,图谋皇位啊!哈哈哈哈开个玩笑,这篇就主要讲讲Linux进程的控制吧~

chestnut_orenge的博客 3210

Linux进程(创建进程、等待进程结束、退出进程)

Linux进程(创建进程、等待进程结束、退出进程) 1.创建进程 #include <sys/types.h> #include <unistd.h> pid_t fork(void); fork()函数用来创建一个进程,创建成功返回0,失败返回-1。 实例 #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int ma

pk296256948的博客 2504

练习1 Linux系统进程管理

代码测试不通过可尝试右键将代码格式化

m0_74620645的博客 777

【Linux】进程控制

本文回顾了进程创建,并进行更深入的理解,学习进程终止的概念、操作和原因,对退出状态码和错误码进行介绍;接着又介绍进程等待,什么是进程等待、为什么要进程等待、如何进行进程等待,进而详细介绍了wait和waitpid的用法和原理。

muyuteacher的博客 1240

3.2 进程篇-API操作:创建/使用 等待/退出

wait

weixin_43690845的博客 384

Linux进程创建fork、进程退出exit()、进程等待waitpid()

虽然通过标题,我们就轻易的知道了这三个函数的作用,可是,你真的了解这几个函数码?

qq_61932634的博客 1197

Linux 进程的控制

学习进程创建学习到进程等待学习到进程程序替换微型shell,重新认识shell运行原理学习到进程终止认识在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。进程调用fork,当控制转移到内核中的fork代码后,内核做:分配新的内存块和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加子进程到系统进程列表当中fork返回,开始调度器调度当一个进程调用fork。

weixin_73496371的博客 904

Linux应用开发基础知识——进程学习1(二)

本文介绍了进程的基本概念和创建管理方法。主要内容包括:1.进程与程序的区别,以及进程标识符、父子进程关系;2.进程创建方法(fork和vfork函数)及其区别;3.子进程退出的两种方式(正常退出和异常退出);4.等待子进程退出的必要性及相关函数(wait和waitpid);5.孤儿进程的产生及处理机制。文章通过实例演示了进程创建和管理的具体操作,并解释了相关系统调用的使用方法和注意事项。

2301_80366509的博客 743

【Linux】进程控制的详细介绍

在此之前,我们学过进程的概念,进程的状态,进程地址空间等一系列进程相关的问题。本章我们继续学习进程,我们要来学习一下进程的控制,关于进程等待,进程替换等问题。

weixin_42976474的博客 1162
上一篇: 【python项目实践】ACVA航空公司客户价值分析
下一篇: 初识动静态库
supdriver
博客等级 码龄3年 192粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值