【Linux】进程与可执行程序的关系fork创建子进程写实拷贝的理解

2024-03-18 05:52

本文主要是介绍【Linux】进程与可执行程序的关系fork创建子进程写实拷贝的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、进程与可执行程序之间关系的理解

        系统会将此时在系统运行的进程的各种属性都以文件的形式给你保存在系统的proc目录下。运行一个程序的时候,本质就是把磁盘中的程序拷贝到内存中,当一个进程运行起来的时候,它本质已经和磁盘中的可执行程序没有直接关系了。

 当前我的myprocess程序正在运行

 而此时我将其对应的可执行程序删掉

这个进程所对应的可执行程序已经被语法高亮了,证明已经被删掉了 

 

         而此时我的可执行程序仍在运行,这也从侧面证明了当一个进程运行起来的时候,它本质已经和磁盘中的可执行程序没有直接关系了。从上面的截图中我们也可以看到,/proc目录下的虚拟文件系统是会记录下进程的工作目录和对应可执行程序的路径,/proc目录下记录的进程信息与PCB中的某些信息有重叠,比如说PCB中同样也会记录下进程的工作目录和对应可执行程序的路径。

二、通过系统调用创建进程

fork:创建子进程

        fork之后有两个执行分支,fork之后代码共享,也就是说fork之后的代码父进程和子进程都会执行。下面的5986进程就是bash进程。

     #include <stdio.h>2 #include <unistd.h>3 int main()4 {5     printf("before fork : pid:%d ppid:%d\n", getpid(), getppid());6 7     pid_t id = fork();8 9     printf("after fork : pid:%d ppid:%d returnid: %d\n", getpid(), getppid(), id);10 11                                                                                                                            return 0;}

        第二条printf语句在fork之后,为父子进程共享,所以第二条printf语句会打印两次。我们也可以看到,其中父子进程fork的返回值是不一样的,父进程fork返回的是子进程的pid,子进程返回的是0。

 

        那这里就会有疑问了,为什么fork给父进程返回子进程的pid,给子进程返回0?原因是在进程中,一个父进程可能会有多个子进程,父进程想要管理子进程必须通过子进程的标识符,所以父进程必须知道子进程的标识符,而子进程只需要关心自己是否成功创建了,所以返回0。

        那fork函数为什么会返回两次呢?原因是fork本身是一个系统调用函数,fork内部本身也会有很多代码的,当fork函数执行到最后return pid的时候,它的核心工作已经做完了,子进程其实已经被创建出来了,return pid也是一条语句,既然父子进程已经都被创建出来了,那么父子进程当然都可以执行return pid语句咯,所以return pid被执行了两次,所以fork就会返回两次。

        那上面的id可是同一个变量啊,怎么会即大于零,又等于零呢?这和linux中的虚拟地址有关,也就是说,一个变量可以指向不同的地址空间。

写实拷贝

        任意进程之间是具有独立性的,不会互相影响创建一个进程的时候,系统中就会多一个进程,当子进程创建时,系统就必须为子进程创建出一个全新的PCB(task_struct),父进程会把自己PCB中很多内容拷贝给子进程的PCB,也就是说,子进程被创建,是以父进程为模版的进程都有自己的代码和数据,系统创建出来的子进程的PCB默认就会指向父进程的代码和数据,想让父子进程分别执行不同的程序,那就可以在代码中根据父子进程fork返回值的不同设置ifelse语句,让父子进程分别执行不同的代码。上面说到父子进程共享代码和数据,当父子进程任意一方要对数据进行修改时,都可能会对另一方造成影响,上面又说到任意进程之间是具有独立性的,不会互相影响,那么这时操作系统就会介入,将要修改的数据给子进程(以子进程修改数据为例)拷贝一份,让子进程修改拷贝的这一份数据,子进程也不再指向原来的那一份数据,而是指向修改拷贝的这一份数据。这就叫做写实拷贝

这篇关于【Linux】进程与可执行程序的关系fork创建子进程写实拷贝的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/821378

相关文章

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对