【Linux】进程概念III --fork函数解析

news2025/5/25 12:21:36

img

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。

本篇导航

  • 0. 创建进程
  • 1. 认识fork函数
  • 2.使用Fork函数
  • 3.关于fork的为什么
    • 3.1 一个函数如何返回两次?fork究竟在干什么?
    • 3.2 为什么要给子进程返回0,父进程返回子进程的PID呢?
    • 3.3 一个变量为什么会有两个不同的内容
  • 4. Bash与子进程

在这里插入图片描述

0. 创建进程

我们介绍了每一个在内存中运行的任务都称为一个进程.那么我们如何自己去创建一个进程呢?

在之前我们可以通过./xxx来运行一段程序,这样这段程序就被加载到内存当中成为了一个进程.这是在指令层面上的创建进程.

例如:

创建了一个名为proce的程序,将其运行.之后输入

ps -ajx | grep proce

image-20231103152448136

就可以查看到当前进程的相关信息.可以看到其PID为58014,PPID为57120

我们在代码中可以通过

getpid() getppid()来获取当前进程的PID和PPID,被包含在 **<unistd.h> <sys/types.h>**中,返回值为:pid_t 类型

在man二号手册中可以看到对其的相关介绍,说明其为一个系统调用接口

常见的节号包括:

  • 1:用户命令
  • 2:系统调用
  • 3:C库函数
  • 4:设备和特殊文件
  • 5:文件格式和约定
  • 6:游戏和演示
  • 7:杂项
  • 8:系统管理命令

屏幕截图 2023-11-03 213748

image-20231103213847667

那么我们在代码中如何去创建一个进程呢?

1. 认识fork函数

在代码层面中,我们可以使用fork去创建我们的子进程.

我们先来简单看下这个函数的接口说明,在man二号手册中可以看到对其的相关介绍.说明fork是一个系统调用接口

常见的节号包括:

  • 1:用户命令
  • 2:系统调用
  • 3:C库函数
  • 4:设备和特殊文件
  • 5:文件格式和约定
  • 6:游戏和演示
  • 7:杂项
  • 8:系统管理命令
man fork

屏幕截图 2023-11-03 210854

image-20231103210919090

函数接口:

pid_t fork(void)

头文件:

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

返回值:

若成功创建子进程则对父进程返回子进程ID,对子进程返回0

我们来试着使用一下fork函数

2.使用Fork函数

先直接写一个简单的代码

#include <stdio.h>
#include <unistd.h>
int main()
{
    printf("before:\n");
    pid_t id=fork();
    printf("after:\n");
    sleep(1);
  	return 0;
}

编译运行,惊奇的发现:before被打印了一次,after被打印了两次.

image-20231103212759610

我们可以得出一个结论:代码段在fork之后的部分被执行了两次

我们再来看看这份代码:

#include <stdio.h>
#include <unistd.h>
int main()
{
    printf("pid: %d\n",getpid());
    pid_t id=fork();
    if(id>0)
    {
        while(1)
        {
            printf("my pid : %d , my parent :%d,id:%d\n, ",getpid(),getppid(),id);
            sleep(1);
        }
    }
    else if(id==0)
    {
        while(1)
        {
            printf("my pid : %d , my parent :%d,id:%d\n",getpid(),getppid(),id);
            sleep(1);
        }
    }
    return 0;
}

image-20231103221733998

  • 居然在一份代码中既执行了if,又执行了else.这意味着id既 >0 又 <=0

​ 这在我们过去的学习中是不可能出现的事情.

  • 根据之前所学,fork()对父进程返回子进程PID,对子进程返回0

    所以 249101是父进程,249102是子进程

现在肯定有以下疑问:

  1. 一个函数如何返回两次?
  2. 为什么要给子进程返回0,父进程返回子进程的PID呢?
  3. 一个变量为什么会有两个不同的内容
  4. fork究竟在干什么?

3.关于fork的为什么

在将之前,我们先来理解下这个概念:子进程 创建时会和父进程共享内存中的代码与数据

80d9fb610e3f18a4441e5584b71bb21

这里只是将他们分开来看了,实际中是使用同一个地址上的内容

3.1 一个函数如何返回两次?fork究竟在干什么?

我们这两个问题一起来看.

假设这是一份fork函数的伪代码

pid_t fork()
{
    创建子进程task_struct 
    填充PCB对应内容
    让父子进程指向相同的代码
    可以被CPU调度运行了
 	子进程创建完成   
        
    return ret;
}

注意看最后的一步return ret,此时子进程已经被创建出来了.他共享到了return ret.所以父子进程都需要返回一个ret的值;

我们可以大胆假设:

  • **ret为一个被初始化为0的变量.在填充子进程对应PCB这一步中,ret被赋值为子进程对应的PID.**但此时ret还未被子进程共享.

    子进程共享时,仅共享到了未被赋值的ret,所以返回时因为都有return 所以返回两次

3.2 为什么要给子进程返回0,父进程返回子进程的PID呢?

这是为了方便我们对进程进行管理.

如同上面的代码,我们通常情况下,希望父进程和子进程做不同的事情.所以需要对其进行分流

3.3 一个变量为什么会有两个不同的内容

这里可以先简单的理解为发生了 写时拷贝

虽然父子进程共享代码中的数据,但当任何一个进程需要修改变量中的内容时,会拷贝一份新的数据供修改对象使用.

这里后面谈进程地址空间时会详细解释.

4. Bash与子进程

我们运行起刚刚的进程后,用ps查看发现父进程的PPID(父进程的父进程)为80738.这是什么呢?

image-20231103224811352

发现其为zsh(一个Bash)

image-20231103225006415

的数据供修改对象使用.

这里后面谈进程地址空间时会详细解释.

平常我们在命令行中输入一个指令,bash负责解释完这个指令会新起一个子进程去运行本条指令.
image-20230905164632777

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0-1矩阵列互斥问题——回溯法 Python实现

三、 0-1 矩阵的列集互斥问题。给定一个 m n m \times n mn 的 0-1 矩阵 A \mathrm{A} A 。定义列互斥为: 对于矩阵 A A A 中的任意两列 i i i 和 j j j, 如果在对应的每一行上, i i i 和 j j j 不存在同时为 1 的情况, 则称列 i \mathrm{i} i 和 j \mathrm{j} j 互斥…

Redis-命令操作Redis->redis简介,redis的安装(Linux版本windows版本),redis的命令

redis简介redis的安装&#xff08;Linux版本&windows版本&#xff09;redis的命令 1.redis简介 Redis是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列代理。 它支持字符串、哈…

零基础入门Python,主要该学些什么?一文详解。

文章目录 前言一、Python开发基础二、Python高级编程和数据库开发三、前端开发四、WEB框架开发五、爬虫开发六、全栈项目实战七、数据分析八、人工智能九、自动化运维&开发十、高并发语言GO开发关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精…

Nginx的location优先级和重定向

Nginx的location有优先级级和匹配方式&#xff1a; 在http模块有server,在server模块才有location,location匹配的是uri /test /image 在一个server当中有多个location,如何来确定匹配哪个location。 Nginx的正则表达式&#xff1a; ^:字符串的起始位置 $:字符串的结束位…

推荐彩虹知识商城源码

彩虹知识商城7.0.3小森升级版新增供货商开心学习版&#xff0c;新增邮件提醒功能&#xff0c;支持给用户发订单、结算等邮件通知&#xff0c;支持给管理员发送提现、域名审核等邮件通知&#xff0c;支持设置手续费最低扣除金额&#xff0c;修复了其他一些已知问题。 演示地址&…

工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化

业务流程是由“活动”&#xff08;或称“工作任务”&#xff09;构成的&#xff0c;在企业里的所有工作是不是都叫流程&#xff0c;或者属于流程的一部分&#xff0c;这个概念很绕&#xff0c;我觉得没有必要去做学究气的辨析。我曾经提出过一个从工作的两个特性&#xff08;产…

x86保护模式笔记

多任务 调用门权级规则 合法调用门g1定义: 门g1.DPL 贱于或等于 门g1.目标段.DPL若 代码段p1.CPL 优于或等于 门g1.DPL 则 p1 正常 call g1TSS 权级规则 权级规则4. p代码段CPL d数据段DPL: 判定p访问d 若 p代码段CPL < d数据段DPL, 则p能访问d …

听听ChatGPT对IT行业的发展和就业前景的看法

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:PYTHON学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 (1)判断素数 写法1: 写法2: (2)计算1-100的偶数之和 写法1: 写法2: (3)计算1-100的奇数之和 (4)多层循环 IT行业哪个方向比较…

腾讯云双十一云服务器活动:88元1年的云服务器难道不香吗?

腾讯云双十一活动中&#xff0c;有三款轻量应用服务器可享受特惠优惠。这三款服务器分别是2核2G、2核4G和4核8G&#xff0c;价格分别为88元/年、166.6元/年和529元/15个月。对于需要低成本而又高性能的服务器需求&#xff0c;轻量应用服务器是一个理想的选择。 轻量应用服务器特…

Linux常用命令——chattr命令

在线Linux命令查询工具 chattr 用来改变文件属性 补充说明 chattr命令用来改变文件属性。这项指令可改变存放在ext2文件系统上的文件或目录属性&#xff0c;这些属性共有以下8种模式&#xff1a; 语法 chattr(选项)选项 a&#xff1a;让文件或目录仅供附加用途&#xff…

某某盾-滑块验证-自动获取validate值-(逆向js+python)

我是标题 1.从get&#xff1f;网站获取滑块图片以及token1.1获取fp值1.2 获取cb值1.3 模拟发包 2.获取滑块移动距离3.发包获取最终的validate值3.1轨迹生成3.2 check网站发包3.3 获取data值 4.结论 本实验是根据某某盾示例网站 主要分为两个部分 1.从get&#xff1f;网站获取滑…

TypeScript 第一站概念篇

前言 &#x1f52e; 好长一段时间没有写文章了&#xff0c;原因是经历了一次工作变动&#xff0c;加入了一个有一定规模的开发团队&#xff0c;前端算上我有四个人&#xff0c;很欣慰&#xff0c;体验一下团队配合的感觉&#xff0c;在我之上有一个组长&#xff0c;比我年长四…

Portraiture4.0介绍与插件安装包下载

相信有很多需要经常进行图像处理的小伙伴的电脑上都有一款PS软件吧&#xff0c;PS的功能非常强大&#xff0c;各种细节处理都非常细致&#xff0c;但还是需要一些插件来帮我们快速处理图片&#xff0c;能够省去很多时间和精力。今天给大家介绍一款PS磨皮插件&#xff0c;能够快…

【Linux】进程等待

文章目录 进程等待进程等待必要性实验(见见猪跑)进程等待的方法wait方法waitpid**方法**宏的使用方法获取子进程status 阻塞VS非阻塞概念对比非阻塞有什么好处 具体代码实现进程的阻塞等待方式:进程的非阻塞等待方式:让父进程做其他任务 进程等待 进程等待必要性 之前讲过&am…

2023腾讯云双11优惠3年轻量2核2G4M服务器366.6元,三年价哦!

腾讯云3年轻量应用服务器配置为2核2G4M带宽、50GB SSD系统盘双11优惠价格366.6元三年、108元一年&#xff0c;只是限制月流量&#xff0c;套餐自带300GB月流量。腾讯云百科txybk.com分享2023腾讯云双11优惠活动3年轻量2核2G4M带宽优惠价格、购买条件&#xff1a; 3年轻量2核2G…

大模型的“成本瘦身”运动

数据大、参数量大、算力大&#xff0c;大模型的某些能力才会“涌现”&#xff0c;这一点在科技圈广为流传。 做大模型的主流思想是&#xff1a;不要轻易说模型“不行”&#xff0c;如果“它还没行”&#xff0c;那就做得更大一点。 所以&#xff0c;不到一年的时间&#xff0c;…

MySQL InnoDB数据存储结构

1. 数据库的存储结构&#xff1a;页 索引结构给我们提供了高效的索引方式&#xff0c;不过索引信息以及数据记录都是保存在文件上的&#xff0c;确切说是存储在页结构中。另一方面&#xff0c;索引是在存储引擎中实现的&#xff0c;MySQL服务器上的存储引擎负责对表中数据的读…

Visual Studio使用Git忽略不想上传到远程仓库的文件

前言 作为一个.NET开发者而言&#xff0c;有着宇宙最强IDE&#xff1a;Visual Studio加持&#xff0c;让我们的开发效率得到了更好的提升。我们不需要担心环境变量的配置和其他代码管理工具&#xff0c;因为Visual Studio有着众多的拓展工具。废话不多说&#xff0c;直接进入正…

佳易王商超便利店等会员快速积分、积分兑换管理系统软件下载

佳易王商超便利店等会员快速积分、积分兑换管理系统软件下载 一、佳易王会员管理软件大众版 部分功能简介&#xff1a; 1、会员信息登记 &#xff1a;可以直接使用手机号登记&#xff0c;也可以使用实体卡片&#xff0c;推荐用手机号即可。 2、会员卡类型 &#xff1a;可以自…

6.Spark共享变量

概述 共享变量 共享变量的工作原理Broadcast VariableAccumulator 共享变量 共享变量的工作原理 通常&#xff0c;当给 Spark 操作的函数(如 mpa 或 reduce) 在 Spark 集群上执行时&#xff0c;函数中的变量单独的拷贝到各个节点上&#xff0c;函数执行时&#xff0c;使用…