【Linux操作系统】进程详解(上)

2023-05-16

文章目录

  • 一、进程的定义
  • 二、进程的特征
  • 三、进程的组成及其作用
  • 四、进程控制块
    • 4.1 进程控制块定义
    • 4.2 task_struct的内容
  • 五、进程与程序的区别
  • 六、进程与线程的区别
  • 七、进程的种类
  • 八、PID
    • 8.1 PID定义
    • 8.2 特殊PID的进程
  • 九、进程的相关命令
    • 9.1 ps命令
    • 9.2 top/htop命令
    • 9.3 pidof命令
    • 9.4 kill命令
  • 十、进程的状态
  • 十一、进程状态切换的实例(前后台切换)
  • 十二、进程的创建
    • 12.1 进程的创建过程(fork)
    • 12.2 使用fork创建进程(不关注返回值)
    • 12.3 使用fork创建进程(关注返回值)
    • 12.4 进程的执行过程
    • 12.5 父子进程内存空间的问题

一、进程的定义

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。

简而言之就是程序的一次执行过程
进程是正在运行的程序的实例,也就是一个正在执行的任务。
进程是有生命周期的,随着程序的运行而创建,随着程序的结束而终止。
进程是分配资源的最小单位,只要创建了一个进程,就分配了[0-3G]的用户空间。
只要用户执行了一个程序,内核就会创建一个task_struct(PCB)结构体,这个结构体就代表当前的进程。
在进程内部维护了自己的一套文件描述符和缓冲区。只要进程执行结束,那么它的所有的资源都会被操作系统回收。
在这里插入图片描述
时间片轮询实现并发
在这里插入图片描述

二、进程的特征

  1. 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  2. 并发性:任何进程都可以同其他进程一起并发执行
  3. 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
  4. 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进

多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。

三、进程的组成及其作用

进程的组成包含三个部分:进程控制块PCB(task_struct),数据段,程序段。

进程控制块:使一个在多道程序环境下不能独立运行的程序(包含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。
程序段:是进程中能被进程调度程序在CPU上执行的程序代码段。
数据段:一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行后产生的中间或最终数据。

四、进程控制块

4.1 进程控制块定义

为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构。它是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,在创建进程时,建立PCB,伴随进程运行的全过程,直到进程撤消而撤消。
PCB的本质是一个结构体,不同的操作系统中PCB的名字不同。Linux中,PCB名为task_struct,PCB 是控制进程的唯一手段。
每一个进程都有一个进程描述符,这个”进程描述符”即是task_struct,在task_struct里面保存了许多关于进程控制的信息。

4.2 task_struct的内容

每个进程都把它的信息放在task_struct这个数据结构里面,而task_struct包含以下内容:

  1. 标示符(pid):描述本进程的唯一标示符,用来区别其他进程。
  2. 状态:任务状态,退出代码,退出信号等。
  3. 优先级:相对于其他进程的优先级(数越小,优先级越高)。
  4. 程序计数器:程序中即将被执行的下一条指令的地址。
  5. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  6. 上下文数据:保存上下文就是把cpu寄存器中的值保存到内存中;恢复上下文就是把内存中的寄存器值恢复到cpu中去;
  7. I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和正在被进程使用的文件列表。
  8. 记账信息 :可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  9. 其他信息

五、进程与程序的区别

  1. 进程是程序的一次执行过程,它是动态的,具备生命周期,在内存上存放。
  2. 程序是静态的,没有生命周期。在磁盘上存放,程序就是可以可执行文件。
  3. 进程更能真实地描述并发,而程序不能。
  4. 进程具有创建其他进程的功能,而程序没有。
  5. 同一程序可以对应多个进程。

六、进程与线程的区别

通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。

七、进程的种类

进程的种类有三种分别是交互进程,批处理进程,守护进程

  1. 交互进程:交互进程是由shell维护的,通过shell和用户进行交互。
    例如文本编辑器就是交互进程。
  2. 批处理进程:批处理进程会被放到内核的一个队列中,随着队列的运行而运行,它的优先级相对比较低。
    例如gcc编译程序的过程。
  3. 守护进程:守护进程是后台运行的进程,随着系统的启动而启动,随着系统的终止而终止。
    例如windows上的各种服务。

八、PID

8.1 PID定义

PID是进程的唯一标识(进程号),它是一个大于等于0的整数。
在一个系统中能够创建的最大的进程可以通过如下命令查看。
cat /proc/sys/kernel/pid_max
通过命令可知能够创建的最大的进程是131072。
在这里插入图片描述
在操作系统上正在运行的进程都在proc目录下
在这里插入图片描述
执行命令
cd 1980
vi status
在这里插入图片描述

8.2 特殊PID的进程

0(idle):在操作系统启动的时候创建的进程,0号进程是1和2号进程的父进程。如果在操作系统上没有其他的进程执行就执行0号进程。

1(init):1号进程是在0号进程通过kernel_thread函数创建的来的,它就要是用来
在启动的时候初始化各种硬件,应硬件初始化完之后。init进程用来为孤儿进程回收资源。

2(kthreadd):2号进程也是在0号进程通过kernel_thread函数创建的来的,这个进程是调度器进程。

九、进程的相关命令

9.1 ps命令

ps -ef命令:查看进程的父子关系
在这里插入图片描述
UID:用户名
PID:进程号
PPID:父进程号
TTY:是否有终端与之关联,如果没有就是?

ps -ajx命令:查看进程状态的命令(静态)。可以完全替代ps -ef
ps -ajx | grep bash指定搜索bash进程
在这里插入图片描述
PPID:父进程号
PID:进程号
SID:只要新开一个终端就会创建一个会话(SID)
PGID:一个会话内有一个前台进程组和多个后台进程组(PGID),进程组内有多个进程
TTY:是否有终端与之关联,如果没有就是?
TPGID:如果是-1就代表是守护进程
STAT:进程的状态
UID:用户名
TIME:运行的时间
COMMAND:进程名

9.2 top/htop命令

动态查看进程状态的命令
top在这里插入图片描述
htop
在这里插入图片描述

9.3 pidof命令

pidof a.out:查看所有名叫a.out的进程进程号
等价于ps -ajx | grep a.out
在这里插入图片描述

9.4 kill命令

给进程发信号

kill -l:查看操作系统中的信号
在这里插入图片描述
kill -信号号 pid 命令:给系统发信号
kill -2 pid:ctrl+c 结束pid对应的程序
kill -9 pid:杀死pid对应的程序
kill -19 pid:停止pid对应的程序
kill -18 pid:pid对应的进程继续运行
killall 程序名:杀死程序名的进程

十、进程的状态

执行命令man ps
在这里插入图片描述
1.进程的状态

D    不可中断的等待态(信号)
R    运行态
S    可中断的等待态 (信号)
T    停止态
X    死亡态
Z    僵尸态

2.进程的附加状态

<    高优先级的进程
N    低优先级的进程
L    内存锁定
s    会话组的组长
l    进程内包含多线程
+    前台进程

3.特殊状态的进程
孤儿进程:父进程死了之后,子进程就变成了孤儿进程。
僵尸进程:子进程死掉之后,父进程没有为他收尸,此时子进程就是僵尸进程。

在这里插入图片描述

十一、进程状态切换的实例(前后台切换)

#include <stdio.h>

int main(int argc,const char * argv[])
{
    while(1);
    return 0;
}

执行上面程序使进程保持运行态。

可以看见状态R+,进程前台运行
在这里插入图片描述
ctrl+z相当于kill -19 13690
在这里插入图片描述
变成停止态T
在这里插入图片描述
方式1:kill -18 13690使停止态变成后台运行的状态R
在这里插入图片描述
kill -9 13690杀死程序
在这里插入图片描述
方式2: 从停止态变为后台运行的状态 (直接后台运行 ./a.out &)

通过前两步使其变成停止态
通过jobs -l查看所有停止状态的进程
[1]这个1是作业号
在这里插入图片描述
bg 作业号(1是作业号):使进程变为后台运行
在这里插入图片描述
fg 作业号(1是作业号):使进程变为前台运行的进程
在这里插入图片描述
在这里插入图片描述
方式3: 在执行程序的时候使用./a.out &使进程后台运行状态
在这里插入图片描述
注: 后台进程可以向输出信息,但是不要向后台进程输入信息

十二、进程的创建

12.1 进程的创建过程(fork)

进程是通过拷贝父进程得到的。

#include <sys/types.h>
#include <unistd.h>
       
pid_t fork(void);
功能:创建进程
参数:
    @无
返回值:如果成功,子进程的PID会返回给父进程,子进程收到0。
        失败时,父进程中返回-1,不创建子进程,并置为错误码。

12.2 使用fork创建进程(不关注返回值)

fork一次

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,const char * argv[])
{
    fork(); //产生子进程
    while(1); //父子进程都在执行这个while循环
    return 0;
}

在这里插入图片描述
循环fork三次

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,const char * argv[])
{
    for(int i=0;i<3;i++)
    {
        fork();
    }
    while(1);
    return 0;
}

在这里插入图片描述
如果在不关注返回值的情况下,fork n次产生2n个进程

fork子进程的时候会拷贝父进程的缓冲区,多个进程共用一个终端

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,const char * argv[])
{
    for(int i=0;i<2;i++)
    {
        fork();
        printf("-");
    }
    return 0;
}

在这里插入图片描述
结果分析:
在这里插入图片描述

12.3 使用fork创建进程(关注返回值)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,const char * argv[])
{
    pid_t pid;

    pid = fork();
    if(pid == -1){
        PRINT_ERR("fork error");
    }else if(pid == 0){
        printf("这是子进程\n");
    }else{
        printf("这是父进程\n");
    }

    //这里的代码父子进程都会执行
    return 0;
}

12.4 进程的执行过程

进程的执行没有先后顺序,时间片轮询,上下文切换。

12.5 父子进程内存空间的问题

父子进程内存空间是独立的,子进程拷贝父进程的时候遵从写时拷贝。
在这里插入图片描述
哪份被修改了拷贝哪份的,不修改共用一块内存。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux操作系统】进程详解(上) 的相关文章

随机推荐

  • MPU-6050资源介绍

    介绍 作用 xff1a 测量三轴加速度和三轴角速度 测三轴加速度 xff1a 加速度计 测三轴角速度 xff1a 陀螺仪 加速度计具有静态稳定性 xff0c 动态不稳定性 陀螺仪具有静态不稳定性 xff0c 动态稳定性 需要互补滤波 xff
  • STM32硬件I2C

    以I2C2为例子 硬件I2C不需要我们手动去翻转电平 首先配置I2C xff1a 配置GPIO xff0c 配置复用功能I2C 配置复用开漏 xff0c 使能I2C I2C起始条件函数 64 param I2Cx where x can b
  • 最简单的 DRM 应用 & drm设备不工作

    https zhuanlan zhihu com p 341895843 https zhuanlan zhihu com p 75321245 编写最简单的 DRM 应用 主程序 xff1a int main int argc char
  • spi通信

    特点 常规四线通信方式 一根片选线 xff0c 一根时钟线 xff0c 两根数据线 xff1a 一根是主进从出线 xff0c 一根主出从入线 同步 xff0c 全双工 xff0c 通信方式 和谁通信就将谁的片选线拉低 xff0c 每增加一个
  • FreeRtos任务通信之消息队列

    入队阻塞 xff1a 往队列写数据时 xff0c 队列满时的阻塞 当阻塞结束时 xff0c 优先级最高的任务优先进入就绪态 xff0c 同 优先级时 xff0c 阻塞时间最长的进入就绪态 出队阻塞 xff1a 读队列时 xff0c 队列为空
  • STM32F103C8T6 ADC功能

    12位逐次逼近型ADC 1us转换时间 输入电压0 3 3v和转化范围0 2 12 1 xff08 0 4095 xff09 成线性关系 2个ADC资源 xff0c ADC1和ADC2 xff0c 10个外部通道 有两种转换单元组 xff1
  • stm32串口实验

    目录 xff08 一 xff09 STM32 串口简介 二 软件设计 xff08 三 xff09 效果 xff1a 1 实现功能 xff1a STM32 通过串口和上位机的对话 xff0c STM32 在收到上位机发过来的字符串后 xff0
  • 基于stm32的GPS解析数据

    目录 1 GPS模块 2 GPS发送的数据格式 3 软件设计 3 1配置好串口 3 2然后写串口中断函数 效果 1 GPS模块 2 GPS发送的数据格式 GPRMC lt 1 gt lt 2 gt lt 3 gt lt 4 gt lt 5
  • 大疆遥控控制M3508电机二(基于HAL库)

    接上一篇文章 xff0c 话不多说直接开始 一 打开我们创建的工程文件 xff0c 先就建立一个文件夹用来存放我们写的子文件 xff08 不建立也行 xff09 xff0c 然后建立pid h xff0c pid c存入我们建立的文件夹中
  • aruco_ros 在相机图像中显示的坐标轴姿态与TF发布的姿态不一致 解决方法

    aruco ros 在相机图像中显示的坐标轴姿态与TF发布的姿态不一致 解决方法 运行环境问题描述解决方案 运行环境 系统版本 xff1a Ubuntu 16 04 ROS版本 xff1a Kinetic 问题描述 在进行手眼标定过程中 x
  • 安装vscode的时候没有勾选快捷方式用vscode打开文件,如何用vscode快速打开文件或者文件夹

    1 需要在注册表里面添加内容可以实现 xff0c 下面有一种简单的方式来完成这个操作 2 需要在电脑桌面新建一个Open File With VS code reg 文件然后用打开文件 xff0c 将以下代码复制 Windows Regis
  • C语言学习笔记->const和define区别

    1 define 是预编译指令 xff0c 而const 是普通变量的定义 define定义的宏是在预处理阶段展开的 xff0c 而const定义的只读变量在编译运行中使用 2 const定义的是变量 xff0c 而define定义的是常量
  • 基于栈、寄存器的优缺点

    基于栈的优点 xff1a 对硬件的依赖不高 xff0c 跨平台性 缺点 xff1a 使用的指令集高基于寄存器的优点 xff1a 相对于栈来说 xff0c 寄存器的性能高 xff0c 使用的指令集少 Java代码执行流程 xff1a java
  • Makefile文件的编写(实例详解)

    1 什么是Makefile xff1f 一个工程中的源文件不计其数 xff0c 其按类型 功能 模块分别放在若干个目录中 xff0c Makefile定义了一系列的规则来指定哪些文件需要先编译 xff0c 哪些文件需要后编译 xff0c 哪
  • 用C语言实现万年历的代码及思路(详细教程)

    万年历程序要求 xff1a 1 当选择1的时候 xff0c 输入年 xff0c 打印输入的这一年12月的日历 2 当选择2的时候 xff0c 输入年 月 xff0c 打印输入这一年这一月的日历 实现效果 xff1a 选择1时 span cl
  • 有符号数和无符号数参与运算时的问题

    陷阱题目 xff1a 下面的代码输出是 xff08 xff09 span class token macro property span class token directive hash span span class token di
  • 【Linux网络编程】基于UDP实现多人聊天室

    文章目录 一 UDP的概念1 1 UDP1 2 UDP特点 二 采用UDP实现多人聊天室原因三 多人聊天室项目功能四 实现多人聊天室项目流程分析4 1 前期准备4 1 1 定义结构体4 1 2 定义链表 4 2 多人聊天室服务器4 2 1
  • 【C++】C向C++的知识过度(上)

    文章目录 一 C与C 43 43 的区别1 1 C是面向过程的1 2 C 43 43 是面向对象的1 3 编译器的区别 二 C与C 43 43 默认代码的不同三 命名空间3 1 关键字 96 namespace 96 去定义自己的名字空间
  • 【C++】四种类型转换 | C++异常处理机制 | C++11新特性之右值引用和移动构造

    文章目录 一 C 43 43 中的四种类型转换1 1 静态类型转换1 1 1 C 43 43 中内置类型的转换1 1 2 C 43 43 中的有继承关系存在的场景下的类型强转 1 2 动态类型转换1 3 常类型转换1 4 解释类型转换 二
  • 【Linux操作系统】进程详解(上)

    文章目录 一 进程的定义二 进程的特征三 进程的组成及其作用四 进程控制块4 1 进程控制块定义4 2 task struct的内容 五 进程与程序的区别六 进程与线程的区别七 进程的种类八 PID8 1 PID定义8 2 特殊PID的进程