Linux进程——子进程详解

文章目录

    • 查看进程的另一种方式
    • 如何创建子进程
    • fork函数详解
      • fork函数的用法
      • fork函数做了什么
      • 为什么fork有两个返回值
      • 父子进程的运行顺序是什么样的
      • 为什么fork函数的两个返回值不同

在上一节中我们简单介绍了进程的概念,还有父进程和子进程

这篇文章的主要内容是介绍如何使用fork函数创建子进程,fork函数的一些特点

查看进程的另一种方式

在上一节中主要使用ps命令列举进程条目,但我们知道,在Linux系统中,一切皆文件

因此所谓的进程条目,本质上也是存着的一个动态文件proc,这里面存放着所有的进程信息

因为这个文件是会随着进程的改变实时更新其中的内容,因此我们称之为动态文件

我们可以使用ls /proc/查看所有进程文件,也可以在其后加上特定进程的pid,查看特定进程

例如

image.png

我们同样可以创建一个死循环,然后来使用这个命令来查看其中的内容

image.png

在我们自行创建的进程当中存在着许多文件,这里有两个文件值得我们注意,一个是exe文件,另一个是cwd文件

其中exe文件指的是可执行程序的位置,而cwd代表默认的当前文件,或者可以简单理解为当前的文件路径,就好比pwd命令查看当前路径,他就是从cwd文件获取的路径

如何创建子进程

众所周知Linux的底层是使用c语言实现的,因此所谓的创建进程本质上就是调用了一个c语言函数,也就是用代码创建进程,而我们用户使用代码创建进程称之为系统调用,函数是fork

我们可以在c语言中写一个函数来直接调用看看情况

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{printf("这是一个进程,pid是%d\n",getpid());fork();printf("This is a process, pid is %d\n",getpid());sleep(1);return 0;
}

image.png

这里我们发现了第一个不对劲的地方,我明明只打印了一次英语的部分,但是输出结果却有两份

我们继续观察,如果我将这部分放在死循环里是什么样的

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{printf("这是一个进程,pid是%d,ppid是%d\n",getpid(),getppid());while(1){fork();printf("This is a process, pid is %d, ppid is %d\n",getpid(),getppid());sleep(1);}return 0;
}

image.png

这里我们打印了进程id和父进程id,我们可以发现一些规律,其实也就是进程创建的子进程一直以他本身为父进程,然后这里的每一个子进程,又会一直创建他的子进程

fork函数详解

fork函数的用法

通过上面的代码,我们其实可以发现一点规律,在fork之前的代码,只有父进程执行,而fork之后的代码,父子进程都要执行

fork函数还有一个特别反直觉的内容,就是他的返回值有两个,分别返回给父子进程,并且父子进程受到的返回值还不相同

我们先不纠结这里的原理是什么,他这么设置肯定有这么设置的道理

首先返回值不同其实就可以在一段代码中区分父子进程了,这样就不至于写出特别乱的代码(执行起来特别乱,因为父子进程都会执行fork之后的代码),他的用法如下

int forkid = fork();
if(forkid==0)
{// 子进程代码
}
else
{// 父进程代码
}

这样就可以实现不同的进程,执行不同的操作的用法

我们可以使用这样的代码查看fork的返回值

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{printf("这是父进程,pid是%d\n",getpid());pid_t id = fork();if(id==0){while(1){printf("这是子进程,在执行操作二,pid是%d,ppid是%d\n",getpid(),getppid());sleep(1);}}else{while(1){printf("这是父进程,在执行操作一,pid是%d,ppid是%d\n",getpid(),getppid());sleep(1);}}return 0;
}

image.png

这样子两个执行流其实就不会互相干扰了

fork函数做了什么

当fork函数创建子进程时,操作系统就会以父进程为模板创建子进程的PCB,但此时子进程是没有代码和数据,他只能和父进程共享代码和数据,父子进程也就会执行相同的代码了

那么又因为一个父进程可以创建很多子进程,但是每一个子进程都有唯一确定的父进程,这就确保了父进程id的唯一性,类似于树的结构,当父进程获取到子进程id时,也就方便了父进程管理子进程

为什么fork有两个返回值

首先,我们需要了解一些fork函数大概的工作流程

  1. 找到父进程的PCB对象
  2. 为子进程开PCB,malloc(task_struct)
  3. 以父进程PCB为模板,初始化子进程PCB
  4. 让子进程PCB执行父进程中的代码和数据
  5. 让子进程进入调度队列,等待CPU处理
  6. 返回

所以这里就很明显了,其实在子进程开新的PCB之后,就已经有了两个进程,两个执行流,自然也就有了两个函数、两个返回值,并且这两个函数还分属于不同的进程,才能有不同的返回值

父子进程的运行顺序是什么样的

这个问题看似很奇怪,但是考虑到我们CPU同时只能执行一项任务,也很好思考,进程的调度必须要有一个顺序

这里其实就说明,父子进程的运行顺序其实并非由用户决定,而是由PCB中的调度信息决定的,例如进程优先级、算法信息等,我们后面也会进行介绍

为什么fork函数的两个返回值不同

前面我们说明了为什么fork函数会由两个返回值,但是这两个返回值明明是一个变量,那么为什么同一个变量会有不同的值呢

首先我们需要明确一点,父进程本质上只是一个管理关系,父子进程本质上仍然是两个独立运行的进程,也就是说kill掉父进程,子进程仍然会运行(这时候子进程就处于一个特殊的状态,我们后续也会介绍),同样的kill掉子进程,父进程也是不会受到影响的

那么问题还是没有解决,操作系统是如何做到让数据在每个进程中都有一份的呢,其实就是我们之前学到类和对象管理的写时拷贝

当子进程想要使用父进程的数据时,就会拷贝一份到子进程的PCB中,这样子进程的变量如何变化也不会影响到父进程了,因此当fork函数返回时,也会触发写时拷贝,此时两个进程的id就不同了

fork函数的细节其实还有很多,但目前我们的目标还只是初步了解,等我们深入学习之后再回头来学习即可

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

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

相关文章

eNsp公司管理的网络NAT策略搭建

实验拓扑图 实验需求&#xff1a; 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带…

护网HW面试——redis利用方式即复现

参考&#xff1a;https://xz.aliyun.com/t/13071 面试中经常会问到ssrf的打法&#xff0c;讲到ssrf那么就会讲到配合打内网的redis&#xff0c;本篇就介绍redis的打法。 未授权 原理&#xff1a; Redis默认情况下&#xff0c;会绑定在0.0.0.0:6379&#xff0c;如果没有采用相关…

暴雨让服务器不怕热҈热҈热҈热҈

在AI算力呈几何倍数增长的趋势下&#xff0c;算力逐渐朝着“高性能、高密度、高耗能“发展。在高耗能的算力下&#xff0c;AI服务器功率已逐步逼近风冷散热极限&#xff0c;而液冷作为更加高效、低能耗的制冷技术&#xff0c;逐渐成为了高密度算力散热场景的首选方案。 液冷的…

网络安全----防御----防火墙nat以及智能选路

前面要求在前一篇博客 网络安全----防御----防火墙安全策略组网-CSDN博客 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的ht…

Jenkins中Node节点与构建任务

目录 节点在 Jenkins 中的主要作用 1. 分布式构建 分布式处理 负载均衡 2. 提供不同的运行环境 多平台支持 特殊环境需求 3. 提高资源利用率 动态资源管理 云端集成 4. 提供隔离和安全性 任务隔离 权限控制 5. 提高可扩展性 横向扩展 高可用性 Jenkins 主服务…

Python excel知识库批量模糊匹配的3种方法实例(fuzzywuzzy\Gensim)

前言 当然&#xff0c;基于排序的模糊匹配&#xff08;类似于Excel的VLOOKUP函数的模糊匹配模式&#xff09;也属于模糊匹配的范畴&#xff0c;但那种过于简单&#xff0c;不是本文讨论的范畴。 本文主要讨论的是以公司名称或地址为主的字符串的模糊匹配。 使用编辑距离算法进…

ffmpeg 时间相关--时间基,timebase,pts,dts,duration

在编码时 video 的情况如下&#xff1a; 1. 在 yuv 数据 阶段&#xff0c;和时间相关参数如下&#xff1a; yuv数据我们在设置的时候要 设置参数&#xff0c;其中和时间相关的是 yuvfps 和 timebase&#xff0c;yuvfps一般是每秒25帧&#xff0c;yuvfps25&#xff1b;timebas…

Is Temperature the Creativity Parameter of Large Language Models?阅读笔记

最近有小伙伴来问LLM的参数该如何设计&#xff0c;废话不多说来看看paper吧。首先&#xff0c;常见的可以进行调参的几个值有temperature&#xff0c;top-p和top-k。今天这篇文章是关于temperature的。 原文链接&#xff1a;https://arxiv.org/abs/2405.00492 temperature如果…

OSPF.中DBD数据包

指定路由器---DR的身份 备份指定路由器---BDR的身份&#xff08;RID&#xff09;注意在一个广播域中的所有设备DR和BDR的认知必须统一。 只有DR和BDR会监听224.0.0.6的组播地址 会发出多个数据包 作用&#xff1a; 1.用来主从选举&#xff08;没有携带lsa再要信息的DBD报文…

《斯科特·凯尔比的风光摄影手册》读书笔记

写在前面 《斯科特凯尔比的风光摄影手册》读书笔记整理没有全部读完&#xff0c;选择了感兴趣的章节理解不足小伙伴帮忙指正 &#x1f603;,生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c;所以唯一的解决办法就是行动起来&#xff0c;认真做完事情&#xff0c;…

PHP使用,按时间水平分表,跨月多表条件查询数据分页显示

1.创建测试表并添加一些对应数据 sh_user_visit_202405 uid,create_time sh_user_visit_202406 uid,create_time sh_user_visit_202407 uid,create_time2.格式化表 //获取表数组 public function getListByCross($table_prefix, $start_date, $end_date){if($end_date > d…

nginx+lua 实现URL重定向(根据传入的参数条件)

程序版本说明 程序版本URLnginx1.27.0https://nginx.org/download/nginx-1.27.0.tar.gzngx_devel_kitv0.3.3https://github.com/simpl/ngx_devel_kit/archive/v0.3.3.tar.gzluajitv2.1https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20240626.tar.gzlua-nginx-m…

Qt项目:基于Qt实现的网络聊天室---TCP服务器和token验证

文章目录 TCP服务器设计客户端TCP管理者ChatServerAsioIOServicePoolSession层LogicSystem总结 token验证模块完善protoStatusServer验证token客户端处理登陆回包用户管理登陆界面 本篇完成的模块是TCP服务器的设计和token验证 TCP服务器设计 客户端TCP管理者 因为聊天服务要…

游戏服务端设计:任务系统

任务系统的设计 导读 在众多的游戏系统当中,任务系统可谓是缺一不可。它是策划对游戏周期的一种抽象拆分。每个阶段的任务设定和游戏的进度密切相关,可以视其为带有目标的玩法提示和指引。通过完成任务,来了解游戏背景、熟悉玩法,或者是达到某种目标(等级提升/道具获取/条…

C#开发翻译较好的API

用于翻译服务的网站或API&#xff0c;尤其适合C#开发&#xff0c;以下是一些知名的选项&#xff1a; Google Cloud Translation API Google 提供的翻译服务非常强大&#xff0c;支持多种语言&#xff0c;而且有很好的文档和社区支持。您可以使用C# SDK来调用此API。 Microsoft …

LabVIEW心电信号自动测试系统

开发了一种基于LabVIEW的心电信号自动测试系统&#xff0c;通过LabVIEW开发的上位机软件&#xff0c;实现对心电信号的实时采集、分析和自动化测试。系统包括心电信号采集模块、信号处理模块和自动化测试模块&#xff0c;能够高效、准确地完成心电信号的测量与分析。 硬件系统…

计算机视觉之Vision Transformer图像分类

Vision Transformer&#xff08;ViT&#xff09;简介 自注意结构模型的发展&#xff0c;特别是Transformer模型的出现&#xff0c;极大推动了自然语言处理模型的发展。Transformers的计算效率和可扩展性使其能够训练具有超过100B参数的规模空前的模型。ViT是自然语言处理和计算…

STM32+HC-05蓝牙模块学习与使用(内附资料)

引言 随着物联网技术的快速发展&#xff0c;短距离无线通信技术变得日益重要。蓝牙作为一种低功耗、低成本的无线通信技术&#xff0c;在嵌入式系统中得到了广泛应用。本文将详细介绍如何使用STM32微控制器与HC-05蓝牙模块进行通信&#xff0c;实现数据的无线传输。 硬件准备…

prompt第一讲-prompt科普

文章目录 大语言模型输入要求中英翻译助手直接抛出问题描述问题描述&#xff08;详细&#xff09;问题描述案例问题描述案例上下文问题为什么要加入上下文 prompt总结prompt心得 大语言模型输入要求 大语言模型本质上就是一个NLP语言模型&#xff0c;语言模型其实就是接受一堆…

ubuntu服务器安装labelimg报错记录

文章目录 报错提示查看报错原因安装报错 报错提示 按照步骤安装完labelimg后&#xff0c;在终端输入labelImg后&#xff0c;报错&#xff1a; (labelimg) rootinteractive59753:~# labelImg ………………Got keys from plugin meta data ("xcb") QFactoryLoader::Q…