对进程的初步认识以及fork()函数的理解

news2024/11/24 0:48:46

什么是进程 

进程是什么呢?其实解释的通俗浅显一点就是我们运行到内存的程序。我们知道运行一个磁盘里的程序时,会将该程序先加载(将磁盘的数据拷贝)到内存当中,因此该程序就可以称为一个进程。首先我们以Windows操作系统为例, 可以快捷键查看当前正在运行的进程:Ctrl+shift+Esc

进程PCB 

 其实在程序加载到内存之前操作系统这个软件早早的就已经加载到内存当中,而当你双击运行程序加载到内存的过程都是操作系统帮你完成的,而你的内存当中肯定不止有一个进程,所以此时操作系统就需要对你的进程做管理。而管理进程并不是管理这款运行起来的软件,而是管理该进程的PCB(process control block)进程控制块。而对进程PCB的理解是这样的,想要管理进程肯定需要该进程的各种属性以及实时状态,所以操作系统就将该进程以一个结构体的形式存储好该进程的所有属性,而该结构体就称为进程PCB。每一个进程都有对应的PCB,最终都由操作系统进行管理。而cpu处理进程时,拿到的就是进程对应的PCB。


所以最终我们就可以初步了解:进程=可执行程序( 代码和数据)+内核数据结构(PCB就是其中之一,方便OS对进程管理) 

 Linux下的进程PCB

我们知道每个进程都有对应的PCB,而PCB其实是一个统称,就像Linux下的进程PCB具体就是struct task_struct的一个结构体。其实每个进程的PCB都是通过类似于双链表的形式衔接起来得,所以可以说,每个人进程的PCB还存放着两个指针,分别指向前后两个节点的数据。

进程id

而这个struct task_struct(Linux下的PCB)存放的核心数据有哪些呢?自然少不了每个进程对应的标识符:pid(进程id)以及所属标识符:ppid(父进程id)

对一个进程的pid 查看可以用getpid指令,而对一个进程的父进程查看可以getppid指令。


但是有一点:每次运行同一个进程时,该进程的id都会发生改变,但是父进程id却不变

 其实我们的命令行当中,父进程一般都是命令行解释器:shell(Linux下的bash)

所以当我们在命令行中输入的所有指令,运行的程序时,对应的父进程都是bash。

 


进程查看 

1

对进程的查看可以采用 ps axj 指令,查看当前进程。所以可以进行测试:

倒计时的一个程序:

执行结果: 

 运行结果如上,我们知道可执行程序运行起来就算是一个进程了,所以进行查看该进程时就可以查看到,而一旦运行结束,该进程也就没了。

2

还可以通过ls/proc查看所有进程,proc其实就是根目录结构下的一个动态目录结构,该目录下存放着所有存在的进程,而proc下的各个目录都是以存在的进程id命名的,而这里面的内容就是关于对应进程在内存当中的信息以及属性等数据。

这里其实有一个进程属性需要提一下,cwd(当前工作目录),默认情况下,进程启动所处的路径就是当前路径。可以通过chdir()函数更改当前进程的工作目录

Linux中进程的创建

  1. 命令行中直接启动进程
  2. 通过代码来创建进程

其实启动进程的本质就是创建进程,而进程一般是以父进程为模版创建的,进程大部分的属性与父进程相同,只有少部分不同于父进程。

初识fork()

通过代码来创建子进程,就要使用到fork函数,这是一个系统调用。

所以在调用fork函数,只有父进程会执行上面的代码,fork之后会以当前进程(父进程)为模版创建子进程,之后系统会执行两个进程,也就是父子进程一起执行。而且该函数会为父进程返回子进程的pid,为子进程返回0。如果fork失败的话就不会创建子进程,则会为父进程返回-1。

测试用例:

执行结果:不断循环

这个执行结果肯定会充满很多疑问???

前言:

执行可执行程序会先将程序加载进内存中,其实在fork函数的内部会以父进程为模版创建子进程,也就是会将父进程的大部分属性都拷贝到子进程的PCB中。然而子进程并不是从磁盘来的,而是在内存创建的,所以父子进程会共享代码,也就是子进程与父子进程指向同一份代码,但是内部的数据却是独立成各自一份(为了防止一方数据修改而影响另一方的执行结果)。进程之间具有独立性,尽管是父子进程,删除一个进程并不会影响另一个进程,并且进程指向的代码是只读的,并不能做任何的修改,不会受到PCB的影响。

但是为什么子进程不会执行fork之前的代码呢??

其实代码是按照顺序依次执行的,执行当前代码时,操作系统内部寄存器(eip)每次都会保存下一次执行的代码数据,所以fork系统调用执行之后会分流,所以eip指向的就是fork之后的代码,而eip这样的程序计数器也会被子进程继承,所以子进程记录的读写位置就是fork之后。

为什么变量i接受了两个返回值??

fork函数内部会为子进程创建PCB,将父进程的核心代码数据都拷贝给子进程,最后返回。但是实际并不是在fork函数完全执行完以后发生分流的,而是在执行完fork的核心代码之后就已经分流了,所以fork的return会被执行两次,分别为父子进程返回相应的值。     

返回实际就是写入数据 ,将数据写入变量i中,而变量i起初是父进程定义的变量,属于数据,而父子进程数据独立私有,避免数据量过大,造成空间浪费,所以满足写时拷贝特性,因此返回的时候发生了写时拷贝 ,导致同一个变量会有不同的值。                            


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

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

相关文章

特斯拉被称为自动驾驶领域的苹果

特斯拉的自动驾驶技术无疑是居于世界上领先地位的,有人形容特斯拉是自动驾驶汽车领域的苹果。特斯拉发布的Tesla Vision系统只配备了摄像头,不依靠雷达。 这并不是特斯拉唯一和其它对手不同的地方,他们的整个战略都是基于车队和销售产品,而其大多数竞争对手则销售自…

ENVI报错:SaveRasterFile failed:IDLnaMetadata Error

ENVI报错:SaveRasterFile failed:IDLnaMetadata Error 问题描述 ENVI在另存为为TIFF文件时,报了下面这个错误信息 原因 输出路径或者是存放影像的路径里面包含中文,不能包含中文 解决方案 把所有相关路径中的中文改成英文

【第十四届蓝桥杯单片机组】学习笔记(5):PCF8591( AD/DA芯片)

目录 概述功能字芯片寻址控制字A/D转换单通道读取多通道读取 概述 芯片通信方式:IICAIN0,AIN1,AIN2,AIN3:(Analog signal In) 模拟信号输入AOUT:模拟信号输出 功能字 芯片寻址 这是在比赛提供的PCF8591芯…

考虑源荷不确定性的热电联供微网优化(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

华为云云耀云服务器L实例评测|云耀云服务器L实例部署Gogs服务器

华为云云耀云服务器L实例评测|云耀云服务器L实例部署Gogs服务器 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、Gogs介绍2.1 Gogs简介2.2 Gogs特点 三、本次实践介绍3.1 本次实践简介3.2 本次环境规划 四、远程登录华为云云耀云…

【Spring】IoC 与 DI

IoC 与 DI 1. IoC2. DI 1. IoC IoC (Inversion of Control): 控制反转控制反转: 表示应用程序的控制权(对象的生命周期)由应用程序自身的代码反转到容器或框架中。应用程序的组件不再直接控制其依赖项的创建和生命周期管理,而是委托给容器。…

微服务moleculer03

1. Moleculer 目前支持SQLite,MySQL,MariaDB,PostgreSQL,MSSQL等数据库,这里以mysql为例 2. package.json 增加mysql依赖 "mysql2": "^2.3.3", "sequelize": "^6.21.3", &q…

Windows下载AOSP

关于repo repo只是谷歌做的,方便下载安卓源码的工具,本质上是对下载清单进行批量处理,然后使用git克隆。 在windows上下载源码只需要自己处理即可。 具体做法 首先使用git克隆安卓源码清单 git clone https://mirrors.tuna.tsinghua.edu.…

1.Tensor For Beginner - Motivation

为何要研究张量? --主要原因是几何。 Tensors Geometry 了解张量后,可深入了解几何的工作原理 几何的一个例子:爱因斯坦广义相对论中的时空几何 时空是如何弯曲的,宇宙是如何膨胀的。 要从数学上理解这两个问题&am…

归并排序及其非递归实现

个人主页:Lei宝啊 愿所有美好如期而遇 目录 归并排序递归实现 归并排序非递归实现 归并排序递归实现 图示: 代码: 先分再归并,像是后序一般。 //归并排序 void MergeSort(int* arr, int left, int right) {int* temp (int…

Pikachu靶场——越权访问漏洞(over permission)

文章目录 1. over permission1.1 水平越权1.1.1 源代码分析1.1.2 漏洞防御 1.2 垂直提权1.2.1 源代码分析1.2.2 漏洞防御 1.3 越权访问漏洞防御 1. over permission 漏洞描述 越权访问(Broken Access Control,BAC),指应用在检查…

用python表格初级尝试

Excel,我的野心 当我输入3,2 就表示在第3行第2列。的单元格输入数据input输入表头 (input内除了/,空格 回车 标点符号等 全部作为单元格分隔符)由我设置input输入的是行or列 给选项 1. 行 2. 列默认回车或没输入值是列由我设置起…

SEO效果又慢又差,为什么还会有SEO从业者?

“SEO效果又慢又差,这么还会有SEO从业者?”这句话是我今天在某Q群里看到的,其实这个问题我之前也有写过一篇《你问我,为什么还有人做SEO?》。我文中提到过因为搜索无处不在,有搜索后,搜索引擎就…

JavaScript:从入门到进阶的旅程

JavaScript是一种广泛使用的编程语言,为网页和应用程序提供了交互性和动态性。从初学者到资深开发者,JavaScript都是一项值得掌握的技能。在本文中,我们将探讨JavaScript的基础知识,以及一些进阶的概念和技巧。 一、JavaScript简…

Linux系统编程系列之线程

一、什么是线程 线程(Thread)是计算机中的基本执行单元,是操作系统调度的最小单位。线程是进程内的一个独立执行流程,一个进程可以包含多个线程,这些线程共享进程的资源,但每个线程都有自己的独立栈空间以及…

基于SSM的学生事务处理系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

matplotlib从起点出发(9)_Tutorial_9_cycler

0 需求 绘图时有时需要指定几种颜色,或者线型,我们统称为样式,让绘制出的内容在这些样式中循环配置。这时就需要使用到本文所提到的技巧,即cycler. 1 进入教程 本文是自定义属性循环(cycler)设置的演示,用于控制多线…

travel总结:

1、前期准备: 对于项目的大体构成做了一定的了解,然后主要是做后端的数据处理,前期的准备的话创建项目的大体结构,servlet、service、domain、dao、utils的项目结构。以及一些基础的代码的生成,我觉得最主要的是一些基…

leetCode 55.跳跃游戏 贪心算法

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1: 输入…

MySQL的卸载与安装(Linux)

MySQL 前言1. 卸载MySQL1.1 查询与关闭对应MySQL服务1.2 卸载对应安装包 2. 安装MySQL2.1 配置MySQL官方yum源2.2 开始安装MySQL 前言 在这里演示的卸载与安装MySQL都是在Linux的Centos 7.6 环境下,不同环境会有所出入。 为了避免安装和卸载MySQL过程中受到权限的…