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

【Linux系统】进程的生命旅程:从创建到独立的演绎

文章目录

  • 一. 进程概念
  • 二. 查看进程的方法
    • 2.1 getpid() && getppid() 函数
    • 2.2 ps && grep 指令
    • 2.3 /proc 目录
  • 三. 创建进程
    • 3.1 fork() 函数
    • 3.2 关于fork的问题

一. 进程概念

进程(Process)是计算机中正在执行的程序的一个实例。它是操作系统资源分配和调度的基本单位,是操作系统管理计算机硬件和软件资源时的核心概念之一

程序与进程的区别

  • 程序:是一组静态的指令集合(二进制文件),它是一个静态的实体,不会占用计算机的系统资源。

  • 进程:是程序的执行实例,它是动态的,并且在执行过程中会占用系统资源(如CPU时间、内存等)。

内存在同一时间会有成百上千的被加载进来的程序,操作系统是需要对其进行管理的。

操作系统会给每个代码和数据块建立一个struct结构体(进程控制块),结构体存的是对代码和数据块的信息,也有相应的指针指向对应的代码和数据。许多这样的结构体组成双链表,也就是进程列表

进程控制块PCB→Process Control Block

Linux系统中PCBtask_struct

在这里插入图片描述
PCB相关内容:https://www.cnblogs.com/tongyan2/p/5544887.html

总结:进程 = PCB(task_struct) + 对应的代码和数据

进程信息被放在进程控制块中,可以理解为进程属性的集合。操作系统要对进程进行管理,其实就是对描述进程的task_struct形成的数据结构进行增删查改。

注:我们在Linux执行的指令、工具、程序,运行起来都是进程


二. 查看进程的方法

2.1 getpid() && getppid() 函数

getpid()	//获取进程pid
getppid()	//获取父进程pid
  • pid 就是进程的标识符(编号);
  • 这两个函数都是系统调用

我们可以使用 man 2 getpid 来查看相关信息。
在这里插入图片描述

其返回值就是一个整型变量,成功调用返回一个大于0的整数,失败就返回-1。


2.2 ps && grep 指令

ps axj | head -1 ; ps axj | grep mypro	//查看mypro进程相关信息

在这里插入图片描述
由于grep本来也是个进程,查找mypro进程,grep进程就会带上mypro的关键字,那么查出来的进程也会有grep进程,要屏蔽的话就使用grep -v反向匹配

ps axj | head -1 ; ps axj | grep mypro | grep -v grep


2.3 /proc 目录

ls /proc

ls /proc 以文件的方式查看进程,proc目录记录进程信息,每个数字目录代表一个正在运行的进程,进程结束后,对应的目录文件就会删除。

我们先运行一个pid70816的进程。

在这里插入图片描述
再使用ls /proc查看进程信息,可以看到有70816的文件夹。
在这里插入图片描述
让我们直接查看70816的文件夹。

在这里插入图片描述
在这里插入图片描述

  1. exe 代表我们的可执行文件,如果将其删除不会对正在运行的进程造成影响,因为删除的是磁盘上的程序,可执行文件已经被加载在内存里了。

  2. cmd (current work directory)是进程所在的当前文件路径,我们的程序在创建文件时默认是在当前路径下创建的,而当前路径就是通过cmd获取的。

改变文件路径

我们可以使用chdir改变当前进程的文件路径,以下为相关信息。

在这里插入图片描述
结束进程:ctrl+ckill -9 pid


父进程pid不变现象

多次启动进程时,会发现其父进程的pid不变,这是因为该父进程其实就是bash进程,我们执行的程序或者指令大多都是bash的子进程

在这里插入图片描述
当子进程出问题,不会影响bash进行,因为进程具有独立性;当我们启动xshell时,系统自动生成bash进程。

三. 创建进程

3.1 fork() 函数

创建进程需要使用系统调用fork函数。

#include <unistd.h>
pid_t fork();

在这里插入图片描述

  1. fork 系统调用,没有参数,有两个返回值

  2. fork创建进程成功时,给父进程返回子进程的pid,给子进程返回0,失败时返回-1给父进程(没有子进程创建)。这样做的原因是因为父进程与子进程的关系是一对多的关系,将子进程的pid返回给父进程让其可以区分不同的子进程。

  3. 父子进程代码共享,数据各自开辟空间,私有一份(写时拷贝)

在这里插入图片描述
fork的使用示例:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id == 0){//子进程while(1){sleep(1);printf("I am a child process, my pid: %d\n", getpid());printf("\n");}}else{//父进程while(1){sleep(1);printf("I am a fathermak process, my pid: %d\n", getpid());}}return 0;
}

在这里插入图片描述
从上面的现象我们可以看出,id == 0 和 id > 0 同时成立,这是因为当我们创建完子进程后,其实已经存在了两个进程,会共用fork之后的代码,对于父进程 id > 0,对于子进程 id == 0 ,在同一时间内两个进程执行相同代码的不同部分,就会产生上图的结果。

3.2 关于fork的问题

  1. 为什么fork会返回两个值?

在fork函数内部,执行到最后的return语句时,子进程已经创建好了,两个进程就会同时执行return语句,fork就能返回两个值,我们以前认知的一个函数只能有一个返回值是在同一个进程的条件下才成立的。

在这里插入图片描述

  1. 为什么 id == 0id > 0 同时成立?

    • 进程具有独立性。父子进程不同的PCB、代码虽然共享,但是只读的,不会影响独立性

    • 父进程和子进程共用代码和数据,当任意进程尝试修改数据,操作系统在数据被修改前拷贝一份,让目标进程修改这份数据的拷贝。通过这种写时拷贝技术让不同进程的数据独立,从而保证进程的独立性。


Have a good day😏

See you next time, guys!😁✨🎞

请添加图片描述

http://www.dtcms.com/a/331760.html

相关文章:

  • 智能体评测技术与实践:从评估维度到DeepEval实战指南
  • LeetCode Day6 -- 图
  • 速卖通商品详情接口深度开发:从多语言解析到跨境合规处理
  • 从零开始搭建React+TypeScript+webpack开发环境——基于MobX的枚举数据缓存方案设计与实践
  • react + i18n:国际化
  • HTML5二十四节气网站源码
  • 【web自动化】-1- 前端基础及selenium原理和环境安装
  • 传输层协议TCP(3)
  • Observer:优雅管理事件订阅的秘密武器
  • TCP 连接管理:深入分析四次握手与三次挥手
  • C++:浅尝gdb
  • 创客匠人:共情力在创始人IP塑造中的作用
  • 使用Docker和Miniconda3搭建YOLOv13开发环境
  • 如何在 Ubuntu 24.04 LTS Noble Linux 上安装 Wine HQ
  • Java多线程进阶-深入synchronized与CAS
  • RS232串行线是什么?
  • 考研408《计算机组成原理》复习笔记,第五章(1)——CPU功能和结构
  • C#WPF实战出真汁01--搭建项目三层架构
  • 解决 pip 安装包时出现的 ReadTimeoutError 方法 1: 临时使用镜像源(单次安装)
  • LeetCode 1780:判断一个数字是否可以表示成3的幂的和-进制转换解法
  • 基于 LDA 模型的安徽地震舆情数据分析
  • 相机Camera日志实例分析之十四:相机Camx【照片后置炫彩拍照】单帧流程日志详解
  • python——mock接口开发
  • CSS中的 :root 伪类
  • GitHub 仓库代码上传指南
  • svg 转 emf
  • MySQL 事务隔离级别深度解析:从问题实例到场景选择
  • Java 中实体类、VO 与 DTO 的深度解析:定义、异同及实践案例
  • 20道JavaScript进阶相关前端面试题及答案
  • 报数游戏(我将每文更新tips)