当前位置: 首页 > news >正文

初识进程

文章目录

  • 一、进程的概念
    • 1. 进程是什么及进程的管理
    • 2. Linux 下的 pcb
    • 3. 系统调用接口 getpid 和 getppid
    • 4. 系统调用接口 fork

一、进程的概念

1. 进程是什么及进程的管理

在 Linux下 ./binaryfile 运行一个程序或者在 Windows下双击运行一个程序时,程序就变成了一个进程

根据冯诺依曼体系结构,程序运行起来后,程序的代码和数据就会被操作系统加载到内存,但一个程序仅仅被加载到内存,并不代表该程序就是进程

将这里的内存比作学校程序比作人进程比作学校的学生,如果一个人处在学校中,并不能说明这个人就是学校的人,如:学校的保安,食堂阿姨等这些并不是学生,只有那些被学校管理起来的,并且信息在学校的学生档案中的人才能被称作学生,所以只有程序被操作系统管理起来,并且程序的代码和数据的相关信息被操作系统记录了,这个程序才被称做进程

在学校中,当学生很多时,我们需要对学生进行管理,在操作系统中,当很多程序运行起来时,加载到内存中的代码便会很多,操作系统便需要对这些代码和数据进行管理

根据我们对管理进行的建模,可以知道操作系统对加载到内存中代码和数据的管理方式:先描述,在组织

  • 先描述:为了管理程序运行后加载到内存中的代码和数据,操作系统采用了一个结构体对象 pcb,用来描述加载到内存中的代码和数据的相关属性,其中 pcb 中有一个内存指针,用来指向内存中的代码和数据
    在国内的教材中 pcb(process control block) 统一称作进程,在国外有的叫做任务,Linux 下的 pcb 称做 task_struck
    进程管理
    进程 = 内核中关于程序的相关结构体 + 程序的代码和数据

  • 在组织:每一个加载到内存中的代码和数据操作系统都会为其创建一个 pcb 对象,因此我们可以在 pcb 对象中在加上 pcb 结构体指针,构成数据结构中的链表
    Linux 下采用双链表的形式组织

当操作系统想新增一个进程时(启动一个程序),只需要创建一个 pcb,然后录入该程序的属性到 pcb 中,然后在链表中插入该 pcb

当操作系统想杀掉一个进程时(结束程序的运行),只需遍历链表,找到该进程的 pcb,然后通过内存指针释放 pcb 指向的内存中的代码和数据,在再链表中释放该 pcb 结点即可

当操作系统想查看一个进程的运行状态时(查看程序运行是否正常),只需要遍历链表,找到该进程的 pcb,然后查看状态信息即可

当操作系统想找到一个优先级别较高的进程执行时(让 CPU 运行指定程序),只需要遍历链表,找到该进程的 pcb,然后通过内存指针找到 pcb 指向的代码和数据,让 CPU 执行即可

通过先描述,再组织的方式,操作系统对进程的管理被完全的转换成了对 pcb 结构体组成的链表数据结构的增删查改

运行的可执行程序都要被操作系统转换为进程来调度以便完成特定的任务,因此当我们运行一个程序时,就称作 创建了一个进程

仅个人当前理解:软件其实就是一个在磁盘上的二进制文件,当软件运行起来后,便需要加载到内存,所以操作系统对进程的管理,便是对软件资源的管理

进程 = 内核中关于进程的相关数据结构 + 进程的代码和数据

2. Linux 下的 pcb

为了操作系统管理进程,需要描述出进程的共同属性,从而产生了结构体 pcb

task_struct 的字段

  • 标识符:描述本进程的唯一标识符,用来区别进程
  • 状态:任务状态,退出代码,退出信号等
  • 优先级:相对于其他进程的优先级
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:包括程序diamante和进程的相关数据结构的指针,还有和其他进程共享的内存块的指针

pcb 和可执行程序的文件属性关系不大

3. 系统调用接口 getpid 和 getppid

如何证明程序运行起来,便成为了一个进程?

当我们创建一个进程时,操作系统就会在 /proc 目录下创建一个该进程 pid 为名的目录,该目录下存在该进程的属性(文件路径等),当进程终止时,/proc 目录中也会删除该进程 pid 为名的目录

预备知识1:
ps ajx:查看系统中所有的进程
ls /proc:查看系统中的所有进程,其中目录名为数字的表示进程的标识符 pid

[starrycat@iZ2vcer6gtjgqa43cdpeeaZ code]$ ps ajxPPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND0     1     1     1 ?           -1 Ss       0   3:57 /usr/lib/systemd/systemd --system --deserialize 170     2     0     0 ?           -1 S        0   0:00 [kthreadd]2     3     0     0 ?           -1 S        0   0:08 [ksoftirqd/0]2     5     0     0 ?           -1 S<       0   0:00 [kworker/0:0H]2     7     0     0 ?           -1 S        0   0:00 [migration/0]
...
[starrycat@iZ2vcer6gtjgqa43cdpeeaZ code]$ ls /proc
1     14     21134  25405  28     350  47   539   6770  854        crypto       interrupts  kpagecount  mtrr          softirqs       uptime
10    1523   21252  25512  280    36   49   557   6771  9          devices      iomem       kpageflags  net           stat           version
101   15631  21262  26     29     365  5    587   7     acpi       diskstats    ioports     loadavg     pagetypeinfo  swaps          vmallocinfo
1019  16     22     27     296    37   50   598   787   buddyinfo  dma          irq         locks       partitions    sys            vmstat
...

预备知识2:
pid_t getpid(void):返回调用该函数的进程标识符 pid,需要包含头文件 <sys/types.h> 和 <unistd.h>
pid_t:有符号整形的 typedef

如果想了解更多关于 getpid 函数的内容,通过 man 2 getpid 即可查看

接下来通过代码证明程序运行起来,便成为了一个进程

在 process.c 中写好如下代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{while(1){printf("我是一个进程了,我的 pid 是:%d\n", getpid());sleep(1);}return 0;
}

证明1:
打开新的窗口,通过命令查看发现,运行的程序 process 可以查到他的进程标识符 pid

其中 ps ajx | head -1 表示获取进程的第一行属性字段(便于观看)
&& 表示当前一条指令执行成功后执行后一条指令
ps ajx | grep process | grep -v grep 表示筛选出 process 的进程,并且去除掉 grep 这个进程
在这里插入图片描述

过程2:
用 ctrl + c 终止程序后,便查找不到该进程了

在这里插入图片描述

终上所述,程序运行起来后就变成了进程


在进程中存在着父子进程的概念

pid_t getppid(void):返回调用该函数的进程的父进程标识符 pid,需要包含头文件 <sys/types.h> 和 <unistd.h>
pid_t:有符号整形的 typedef

在 process.c 中写好如下代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{while(1){printf("我是一个进程了,我的 pid 是:%d,我的 ppid 是:%d\n", getpid(), getppid());sleep(1);}return 0;

不断的执行 process 会发现子进程的进程标识符一直在增加,但是父进程的进程标识符 6771 一直不变,通过 ps 命令后可以发现 6771 这个进程标识符就是命令行解释器 bash,即命令行执行的程序都是通过创建子进程的方式去执行的,是为了避免执行的程序挂了,导致影响 bash 自己

命令行解释器 bash 其实就是在 /bin/bash 的一个二进制可执行程序,因此 bash 也是一个进程
在这里插入图片描述

命令行启动的所有程序,都是 bash 创建的子进程,为了防止子进程挂了,导致影响自己

4. 系统调用接口 fork

命令行是如何创建子进程的呢?

pid_t fork(void):如果创建子进程成功,则给调用该函数的父进程返回子进程的 pid,给子进程返回 0,如果失败则返回 -1,需要包含头文件 <sys/types.h> 和 <unistd.h>

  • 在代码中执行到 fork 语句后,执行流变成了两个执行流
  • fork 之后的代码,父子进程都会执行,因此我们可以用 if 语句来让执行流分流,以便父子进程执行不同的代码块

在 process.c 中写好如下代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t ret = fork();if (ret == 0){// 执行子进程while (1){printf("我是子进程,我的 pid 是:%d,我的 ppid 是:%d\n", getpid(), getppid());sleep(1);}}else if (ret > 0){// 执行父进程 while (1){printf("我是父进程,我的 pid 是:%d,我的 ppid 是:%d\n", getpid(), getppid());sleep(1);}}else {}return 0;
}
  • fork 创建子进程成功之后,父进程和子进程谁先被 CPU 调度运行是由操作系统决定的

可以通过 fork 系统调用来创建子进程

fork 创建子进程的过程:操作系统为了可以管理子进程,会根据父进程的 pcb 创建子进程的 pcb,并且子进程的 pcb 会和父进程的 pcb 指向同一块代码和数据

在这里插入图片描述

虽然父进程创建子进程后,子进程指向父进程的代码和数据,但是不同的进程在运行时是独立的,父子进程在运行时也是独立的

kill -9 pid 功能:杀掉进程

再次运行 process 之后,在另一个窗口中输入 kill -9 父进程 pid,此时子进程任然可以正常运行
在这里插入图片描述

父子进程是如何做到独立的呢?

  • 在代码层面:可执行程序的代码都是二进制机器指令了,是只读的,不可能被修改,因此父子进程可以一起读代码,只需要记住自己进程执行代码的位置即可
  • 在数据层面:Linux 操作系统采用写时拷贝的方式来保证数据的独立性,即:当某一个进程想要修改数据时,操作系统会自己拷贝一份数据到别的位置然后进行修改

为什么一个函数会有两个返回值?
因为一个函数在执行 return 之前,函数的主题功能已经完成了,对于 fork 函数,在 return 之前已经创建好子进程了,此时便有父子进程两个执行流,于是父子进程都会执行 return 语句,也就产生了两个返回值的现象

相关文章:

初识进程

文章目录一、进程的概念1. 进程是什么及进程的管理2. Linux 下的 pcb3. 系统调用接口 getpid 和 getppid4. 系统调用接口 fork一、进程的概念 1. 进程是什么及进程的管理 在 Linux下 ./binaryfile 运行一个程序或者在 Windows下双击运行一个程序时&#xff0c;程序就变成了一个…...

SOAP传输协议

一.HTTP传输协议 超文本传输协议&#xff08;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;&#xff0c;它是基于请求-响应的模式协议&#xff0c;客户端发出请求&#xff0c;服务器端给出响应并返回请求内容。方法如下&#xff0c;HTTP传输协议常…...

<Linux>进程控制

进程控制 文章目录进程控制一、进程创建1.fork函数认识2.写时拷贝3.fork常规用法4.fork调用失败的原因二、进程终止1.进程退出场景2.进程退出码3.进程退出的方式三、进程等待1.进程等待是什么&#xff1f;2.进程等待的必要性3.进程等待的方法3.1.wait函数3.2.waitpid函数4.如何…...

有手就行 -- 搭建图床(PicGo+腾讯云)

&#x1f373;作者&#xff1a;贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛\color{#FF0000}{贤蛋 大眼萌 &#xff0c;一名很普通但不想普通的程序媛}贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛&#x1f933; &#x1f64a;语录&#xff1a;多一些不为什么的…...

“蓝桥杯”递推和递归(一)——取数位

1. 算法简介 递推和递归虽然叫法不同&#xff0c;但它们的基本思想是一致的&#xff0c;在很多程序中&#xff0c;这两种算法可以通用&#xff0c;不同的是递推法效率更高&#xff0c;递归法更方便阅读。 &#xff08;1&#xff09;递推法 递推法是一种重要的数学方法&#…...

蓝桥杯·3月份刷题集训Day02

本篇博客旨在记录自已打卡蓝桥杯3月份刷题集训&#xff0c;同时会有自己的思路及代码解答希望可以给小伙伴一些帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误之处&#xff0c;希望小伙伴们可以在评论区指出来&#xff0c;共勉&#x1f4aa;。 文…...

python --获取内网IP地址

方法一 import socketdef get_local_ip_address():ip_address try:# 获取本机主机名hostname socket.gethostname()# 获取本机IPip_address socket.gethostbyname(hostname)except:passreturn ip_address方法二 import subprocessdef get_local_ip_address():ip_address …...

如何衡量你的Facebook广告活动的成功

投入大量资金和资源在Facebook广告上并不总能带来预期的回报&#xff0c;这很可能是由于缺乏恰当的衡量广告活动成功的方法。在这篇文章中&#xff0c;我们将介绍一些关键的指标&#xff0c;帮助你更好地了解如何衡量你的Facebook广告活动的成功。1.费用每次点击&#xff08;CP…...

Linux对一个目录及其子目录所有文件添加权限

1、chmod指令 chmod是一个改变用户拥有指定文件的权限的命令.r:只读,w:写,x执行.也可以用数字 -rw------- (600) -- 只有属主有读写权限。 -rw-r--r-- (644) -- 只有属主有读写权限&#xff1b;而属组用户和其他用户只有读权限。 -rwx------ (700) -- 只有属主有读、写、执…...

宝刀未老?低代码何德何能受大厂们的推崇

风口之下&#xff0c;低代码蓬勃发展&#xff0c;本文从国内低代码的走红现象引入&#xff0c;浅析低代码发展中的变化趋势&#xff0c;重点探讨如此趋势之下&#xff0c;国内大厂如何通过低代码实现了良性发展。 一、国内爆火的低代码 据Gartner最新报告显示&#xff0c;到2…...

智能扑克牌识别软件(Python+YOLOv5深度学习模型+清新界面)

摘要&#xff1a;智能扑克牌识别软件利用视觉方法检测和识别日常扑克牌具体花色与数字&#xff0c;快速识别牌型并标注结果&#xff0c;帮助计算机完成扑克牌对战的前期识别步骤。本文详细介绍基于深度学习的智能扑克牌识别软件&#xff0c;在介绍算法原理的同时&#xff0c;给…...

SQL优化13连问,收藏好!

1.日常工作中&#xff0c;你是怎么优化SQL的&#xff1f; 大家可以从这几个维度回答这个问题&#xff1a; 分析慢查询日志 使用explain查看执行计划 索引优化 深分页优化 避免全表扫描 避免返回不必要的数据&#xff08;如select具体字段而不是select*&#xff09; 使用…...

【小技巧】公式从docx文件复制到doc文件变成了图片怎么办?

文章目录0、word文件后缀命名1、docx和doc默认的公式编辑方式2、MathTpye公式编辑器3、MathType 运行时错误‘53’&#xff1a;文件未找到&#xff1a;MathPage.WLL4、结束语0、word文件后缀命名 1997-2003的旧版本文件名后缀是.doc   从2007版以后&#xff0c;后缀名是.docx…...

Python3入门与进阶笔记(六):初识类

目录 一些解释 属性 类名建议首字母大写&#xff0c;通常用驼峰规则命名。变量名建议小写&#xff0c;下划线隔开。类最基本的作用是封装。 写在类内非方法中的语句在类加载的时候会执行&#xff0c;且只会执行一次&#xff0c;例如下面的print语句&#xff0c;类加载时就会…...

Prometheus监控实战系列九:主机监控

Prometheus使用各种Exporter来监控资源。Exporter可以看成是监控的agent端&#xff0c;它负责收集对应资源的指标&#xff0c;并提供接口给到Prometheus读取。不同资源的监控对应不同的Exporter&#xff0c;如node-exporeter、mysql-exporter、kafka-exporter等&#xff0c;在这…...

JVM知识整理

JVM知识整理 JVM的主要组成部分 JVM包含两个两个子系统&#xff08;类加载子系统和执行引擎&#xff09;和两个组件&#xff08;运行时数据区与和本地库接口&#xff09; 类加载子系统&#xff1a;根据给定的全限定类名来加载class文件到运行时数据区域中的方法区。执行引擎&a…...

【C++】二叉搜索树

A:你长大后想要做什么&#xff1f; B:写下“快乐”…… A:不&#xff0c;你理解错我的意思了&#xff0c;我是说 B:不&#xff0c;是你理解错了人生…… 文章目录一、二叉搜索树的实现1.struct TreeNode{}2.迭代版本2.1 Insert()插入结点&#xff08;解决链接的问题&#xff09…...

leetcode -- 21. 合并两个有序链表

&#x1f428;目录&#x1f4d1;1. 题目&#x1f6f6;2. 解法- 头插到新链表&#x1f42c;2.1 思路&#x1f42c;2.1 代码实现⛵3. 解法优化 - 带哨兵位&#x1f40b;3.1 思路&#x1f40b;3.2 代码实现&#x1f6a4;4. 题目链接&#x1f4d1;1. 题目 将两个升序链表合并为一个…...

计算机组成原理|第四章(笔记)

目录第四章 存储器4.1 概述4.1.1 存储器分类4.1.2 存储器的层次结构4.2 主存储器4.2.1 概述4.2.2 半导体存储芯片简介4.2.3 随机存取存储器&#xff08;RAM&#xff09;4.2.4 只读存储器&#xff08;ROM&#xff09;4.2.5 存储器与CPU的连接4.2.6 存储器的校验4.2.7 提高访存速…...

【Unity3D-BUG记录】Unity3D中出现“动画片段必须标记为Legacy的警告”消除方法

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在开发中可能会遇到下面的警告&#xff1a; The AnimationClip…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...