fork()出来一个进程,这个进程的父进程是从哪来的?
基本概念
fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.
fork()是一个系统调用,不是一个函数。详细信息可以,man fork。
如何查看进程ID
每个linux进程都一定有一个唯一的数字标识符,称为进程ID(process ID),进程ID总是一非负整数,它的父进程叫PPID。
查看进程ID命令:
ps -ef

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); 返回:调用进程的进程ID
pid_t getppid(void); 返回:调用进程的父进程ID第一个进程init
Linux内核启动之后,会创建第一个用户级进程init,由上图可知, init 进程 (pid=1) 是除了 idle 进程 (pid=0,也就是 init_task) 之外另一个比较特殊的进程,它是 Linux 内核开始建立起进程概念时第一个通过 kernel_thread 产生的进程,其开始在内核态执行,然后通过一个系统调用,开始执行用户空间的 / sbin/init 程序。
fork函数
创建一个进程很简单,先来认识一下fork函数:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
返回:子进程中为0,父进程中为子进程I D,出错为-1
由fork创建的新进程被称为子进程( child process)。该函数被调用一次,但返回两次,两次返回的区别是子进程的返回值是0,而父进程的返回值则是子进程的进程ID。一般来说,在fork()之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的调度算法。
#include <unistd.h>
#include <stdio.h>int main(int argc,char* argv[])
{pid_t pid;if((pid=fork()) == -1){perror("fork\n");return -1;}else if(pid == 0){printf("this is child process\n");printf("The return value %d in child process! My Pid is %d,My ppid is %d\n",pid,getpid(),getppid());}else{//usleep(1000);printf("this is parent process\n");printf("The return value %d in parent process! My Pid is %d,My ppid is %d\n",pid,getpid(),getppid());}return 0;
}
由上图可知,fork被调用了一次,返回了两次,一次是父进程执行,另外一次是子进程执行。
父子进程关系
使用fork系统调用得到的子进程是父进程的处继承了整个进程的地址空间,包括:[进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端]等。

fork出的子进程会继承父进程的文件描述符,如果读写文件,父子进程之间会互相影响。
./run.out 运行的程序父进程是谁?
我们来编写一个例子:
#include <unistd.h>
#include <stdio.h>int main(int argc,char* argv[])
{while(1);return 0;
}例子很简单,就是创建一个死循环的进程,编译执行。
ps -ef 查看进程ID
ps -ef > 1.txt
wj 40762 1648 0 2月23 ? 00:00:16 /usr/libexec/gnome-terminal-server
wj 558001 40762 0 11:05 pts/3 00:00:00 bash
wj 583066 558001 99 16:22 pts/3 00:01:19 ./run.out
从以上log可以看出来,run.out进程PID为583066,它的父进程为 558001,进程558001即为bash进程。
bash 的父进程为:/usr/libexec/gnome-terminal-server
所以大家应该明白,我们打开1个Linux终端,其实就是启动了1个gnome-terminal-server进程。我们在这个终端上执行./run.out其实就是利用gnome-terminal-server的子进程bash通过execve()将创建的子进程装入./run.out

父进程死了,子进程怎么办?
僵尸进程

如上图所示,父进程Process A创建子进程Process B,当子进程退出时会给父进程发送信号SIGCHLD;
如果父进程没有调用wait等待子进程结束,退出状态丢失,转换成僵死状态,子进程会变成一个僵尸进程。当父进程调用wait,僵尸子进程的结束状态被提取出来,子进程被删除,并且wait函数立刻返回。
当父进程调用wait,僵尸子进程的结束状态被提取出来,子进程被删除,并且wait函数立刻返回。
实例:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>int main(int argc,char* argv[])
{if(fork()){while(1){sleep(1);}}return 0;
}上述程序会保证父进程不退出,一直在while(1)中无限循环,而子进程会立刻退出。

由上图可知,父进程是585663,子进程是585664,子进程因为退出后父进程没有调用wait回收子进程资源,所以子进程585664变成僵尸进程defunct。
ps -ax | grep run.out 查看进程状态,进程状态为:Z+

孤儿进程
如果父进程退出,并且没有调用wait函数,它的子进程就变成孤儿进程,会被一个特殊进程继承,这就是init进程,init 进程会自动清理所有它继承的僵尸进程。
实例代码:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>int main(int argc,char* argv[])
{if(fork()){// parent process.}else{//child process.while(1){sleep(1);}}return 0;
}上述程序会保证子进程不退出,一直在while(1)中无限循环,而父进程会立刻退出。孤儿进程:
待确认?
相关文章:
fork()出来一个进程,这个进程的父进程是从哪来的?
基本概念fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.fork()是一个系统调用,不是一个函数。详细信息可以,man…...
结构体内存对齐
结构体相信大家已经了解过了,现在我们深入讨论一个问题,计算结构体的大小 也是很热门的一个考点:结构体内存对齐 先看看下面结构体的大小 typedef struct Test {char a;char b;char c; }Test; 很容易看出答案为3,结构体的大小位…...
【C语言进阶】指针进阶
今日所做之事勿候明天,自我所做之事勿候他人。 --歌德 目录 指针进阶(更深层次的理解): 一.字符指针 二.指针数组 三.数组指针 1.数组指针的定义: 2.&数组名和数组名: 3.数组指针的使用: 四.数组参数,指针参数 1.一维数组传参:…...
java:Class的isPrimitive方法使用
java:Class的isPrimitive方法使用 1 前言 java中Class类的isPrimitive方法,用于检查类型是否为基本类型。java虚拟机创建了int、byte、short、long、float、double、boolean、char这8种基础信息,以及void,一共9种。为这9种类型时…...
TCP 握手过程 三次 四次
蛋老师视频 SYN 同步 ACK 确认 FIN 结束 核心机制是确定哪些请求或响应需要丢弃 SYN、ACK、FIN 通过 1/0 设置开启/关闭 开启SYN后,报文中会随机生成 Sequence序号 用于校验 (应用可能发起多个会话,可以区分) 服务器的同步序…...
windows 下 安裝mysql 5.7.41 (64位) 超简单方式
文章目录1. 安装包下载2.安装步骤3. 服务卸载方式4. 配上 my.ini 常用配置1. 安装包下载 注意,截至2023年2月23日,MySQL所有版本不提供ARM芯片架构的Windows版本(8.0.12开始支持Red Hat系统的ARM版本),所以ARM架构的Windows无法安装MySQL&am…...
二叉树——二叉树的最近公共祖先
二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一…...
数据结构与算法基础-学习-14-线性表之串
一、串的定义由0-n个字符组成的有限序列。(n>0)二、串的相关术语1、子串串中任意个连续字符组成的子序列成为该串的子串。2、主串包含子串的串成为主串。3、字符位置字符在序列中的序号为该字符在串中的位置。4、子串位置子串第一个字符在主串中的位置…...
Mac 快捷键
目录 命令行快捷键 命令行快捷键 control d 命令行中代表发送EOF终止输入 control u 删除光标之前到行首的字符 control k 删除光标之前到行尾的字符(比较常用) control a 移动光标到行首(常用) control e 移动光标到行尾 control l 清屏,相当于clear命令 con…...
【微服务】-微服务环境搭建
目录 2.1 技术选型 2.2 模块设计 2.3 微服务调用 2.4 创建⽗⼯程 2.5 创建商品微服务 2.6 创建订单微服务 2.1 技术选型 持久层: SpingData Jpa 数据库: MySQL5.7 其他: SpringCloud Alibaba 技术栈 2.2 模块设计 --- shop-parent ⽗⼯程 --- shop-product-api 商品微服…...
IGKBoard(imx6ull)-ADC编程MQ-2烟雾传感器采样
文章目录1- ADC介绍2- MQ-2烟雾传感器介绍(1)工作原理(2)MQ-2应用电路3- MQ-2烟雾传感器硬件连接4- ADC驱动配置5- 编程查看当前浓度1- ADC介绍 ADC是Analog-to-Digital Converter的缩写,指模数转换器。真实世界的模拟…...
前端二面vue面试题总结
什么是 mixin ? Mixin 使我们能够为 Vue 组件编写可插拔和可重用的功能。如果希望在多个组件之间重用一组组件选项,例如生命周期 hook、 方法等,则可以将其编写为 mixin,并在组件中简单的引用它。然后将 mixin 的内容合并到组件中…...
时间API在更新,传奇已经谢幕,但技术永远不死
(Bill Joy(左一),Vinod Khosla(左二),Andy Bechtolsheim(右二),Scott McNealy(右一) ) CSDN 博文征集活动(和日期相关的代码和bug):点击这里 各位 “big guys”,这篇博文…...
SQL调优指南笔记22:Gathering Diagnostic Data with SQL Test Case Builder
本文为SQL Tuning Guide 第21章“Gathering Diagnostic Data with SQL Test Case Builder”的笔记。 SQL Test Case Builder 是一种工具,可自动收集在不同数据库实例中重现问题所需的信息。 SQL 测试用例是一组信息,使开发人员能够为遇到性能问题的特定…...
从0开始学python -43
Python3 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。 re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根…...
Kafka基本原理
总述 简介 Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各…...
css3的重点内容
css3的重点内容 浮动 父级边框塌陷问题 浮动的清除 clear:left; //清除左侧浮动 clear:right; //清除右侧浮动 clear:both; //清除两侧浮动解决方案 增加父级元素的高度增加一个空的div,之后清除浮动通过overflow来进行相关元素的修剪给父类添加相应的伪类元素…...
《Roller: Fast and Efficient Tensor Compilation for Deep Learning》
《Roller: Fast and Efficient Tensor Compilation for Deep Learning》 用于深度学习 快速高效的张量编译器 作者 微软亚洲研究院以及多伦多大学等多所高校 摘要 当前编译为了产生高效的kernel时,搜索空间大,通常使用机器学习的方法 找到最优的方案…...
顺丰同城测试开发一面 49min答案,全文7000字,面试总结都在这里了
今天给大家分享一份顺丰同城的测试开发一面面试真题。老规矩,当你看到这份面试题的时候,先不要着急去看答案,你可以想想假如你在面试现场,你会怎么回答?这个思考的过程其实也是很重要的。 全文7000字干货,…...
docker启动容器服务之后访问失败
关于docker启动容器服务之后,宿主机访问失败(解决方法) 注:在进行docker容器启动宿主机进行容器访问时,无需进行网络的配置,docker容器在启动时会自动解决 第一种原因及修改方法 在进行启动的时候&#…...
Mac开发者必备:OpenClaw+Qwen3.5-9B自动化测试流水线
Mac开发者必备:OpenClawQwen3.5-9B自动化测试流水线 1. 为什么开发者需要本地化CI/CD工具 作为一名长期在Mac上开发的全栈工程师,我一直在寻找一种轻量级的自动化测试方案。传统的Jenkins或GitHub Actions虽然强大,但对于个人项目和小团队来…...
BERT文本分割模型5分钟快速部署:零基础搭建智能分段工具
BERT文本分割模型5分钟快速部署:零基础搭建智能分段工具 1. 引言:告别文字“墙”,让长文本秒变清晰段落 你有没有过这样的经历?辛辛苦苦听完一场两小时的线上会议,语音转文字工具生成了一份上万字的逐字稿。你满怀期…...
Hunyuan-MT-7B翻译模型部署:Docker环境隔离实战解析
Hunyuan-MT-7B翻译模型部署:Docker环境隔离实战解析 想让一个支持33种语言互译、性能顶尖的70亿参数大模型,在你的电脑上“一键启动”吗?听起来像是实验室里的高端玩具,但今天我要告诉你,通过Docker,这完全…...
大数据可视化
1. 传播分析评估维度:包含认知(知晓、记忆)、行动(点击、搜索)、情感(喜好、美誉)三个层面传统评估:主要关注广告点击率和观看次数等表面指标深度评估:需要分析广告观看后…...
DeepSeek总结的DuckLake 中的数据内联:为数据湖解锁流式处理
原文地址:https://ducklake.select/2026/04/02/data-inlining-in-ducklake/ DuckLake 中的数据内联:为数据湖解锁流式处理 Pedro Holanda 2026-04-02 TL;DR: DuckLake 的数据内联功能将小批量更新直接存储在目录中,从而消除了“小…...
OpenClaw资源优化:Phi-3-mini-128k-instruct模型量化与推理加速实践
OpenClaw资源优化:Phi-3-mini-128k-instruct模型量化与推理加速实践 1. 为什么需要优化Phi-3-mini-128k-instruct的性能 当我第一次在OpenClaw中接入Phi-3-mini-128k-instruct模型时,就遇到了一个典型问题:虽然这个128k超长上下文模型在处理…...
STM32开发基础与高级应用全解析
1. STM32入门基础概念解析对于刚接触STM32的开发者来说,首先需要理解一些基础概念和架构特点。STM32是基于ARM Cortex-M内核的32位微控制器,与传统的51单片机相比,在性能、外设丰富度和开发方式上都有显著差异。1.1 时钟系统架构STM32的时钟树…...
Linux内核设计哲学:你我承载力的艺术(续)
第七部:设备驱动——与不完美的世界和解7.1 你不是主人,你是仆人设备驱动是内核中最“卑微”的组件。它不和用户直接打交道,不参与核心决策,甚至不拥有任何资源。它只是硬件的翻译官——把内核的标准请求翻译成硬件能懂的指令&…...
温度场与锂枝晶生长的相场电势场及浓度场耦合仿真研究
comsol 锂枝晶仿真——耦合温度场 在相场,电势场和浓度场的基础上耦合了温度场,可以看不同温度对锂枝晶的影响指尖的金属晶体在电解液中野蛮生长,就像寒冬玻璃上的冰花。当我们盯着显微镜观察锂枝晶时,常忽略了一个重要变量——温…...
资深大模型工程师详细讲解:RAG召回率优化三重微调实战
✅ 一、核心策略再解构:从“三层次”到“五维协同链路”原有“数据-索引-查询”三层结构非常精准,但为了更贴近企业级复杂场景,我们进一步抽象为 五维协同链路:维度关键目标是否可微调微调切入点1. 数据生成质量构建高质量正负样本…...
