首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux进程概述

Linux进程概述

作者头像
wenzid
发布于 2021-07-20 04:29:36
发布于 2021-07-20 04:29:36
3.2K00
代码可运行
举报
文章被收录于专栏:wenzi嵌入式软件wenzi嵌入式软件
运行总次数:0
代码可运行

进程的概念

进程是 Linux 事务管理的基本单元,所有的进程均拥有自己独立的处理环境和系统资源。进程的环境由当前系统状态及其父进程信息决定和组成,将某个可执行文件加载到内存中运行,那么就会演变成一个或者是多个进程。(产生多个进程的原因是进程在运行的时候可以再创建新的进程,但是加载的时候只有一个进程),为了更好的理解进程,以我们平时在 Linux 环境下运行一个 C 程序为例进行说明: 代码很简单,hello world:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

int main(void)
{
    printf("hello world!!!!\r\n");
    while(1);
}

如下是在终端执行的命令:

image-20210619160036037

进程和可执行文件的区别

说到这里,有必要说一下程序和进程之间的关系,程序是存放在存储介质上的一个可执行文件,而进程是程序执行的过程。进程的状态是变化的,其中包括进程的创建、调度和消亡,程序是静态的,而对于进程来说是动态的。

我们在终端运行如下命令,可以看到如下的信息:

image-20210619161052672

从上述可以看出,可执行文件在存储时,可以分为:代码区(text)、数据区(data)和未初始化数据区(bss)三部分。对于一个进程来说,一个进程是一个运行着的程序段,一个进程主要包括在内存中宏申请的空间,代码(加载的程序,包括代码段,数据段,BSS)、堆、栈以及内核进程信息结构,打开的文件、上下文信息以及挂起的信号等。下面列出了可执行文件和进程的结构:

image-20210619162214886

进程的资源

为了更好地管理 Linux 所访问地资源,系统在内核头文件 include/linux/sched.h中定义了结构体 struct task_struct来管理每个进程地资源,下图中结构体中一部分成员的代码截图:

image-20210619164701518

图中仅仅知识呈现出一小部分内容,结构体 struct task_struct 主要包括线程基本信息、内存信息、tty 终端信息,当前目录信息、打开的文件描述符以及信号信息,除了这些,还有其他进程属性,例如:PID、PPID、UID、EUID。下图是一个关于结构体的一个示意图:

image-20210619165014962

进程的状态

对于单 CPU 系统来说,在某一个时刻,只能有一个进程处于运行状态,其他进程都处于其他状态,等待系统资源,各个任务根据调度算法在这些状态之间不停地切换。在Linux 2.6.12内核中,用户级进程主要有以下几种状态:就绪/运行状态、可中断地等待状态,不可中断地等待状态,停止状态和僵死状态。下面是代码各个状态的宏定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define  TASK_RUNNING          0    /* 就绪 */
#define  TASK_INTERRUPTIBLE    1    /* 中断等待 */
#define  TASK_UNINTERRUPTIBLE  2    /* 不可中断等待 */
#define  TASK_ZOMBIE           4    /* 僵死 */
#define  TASK_STOPPED          8    /* 停止 */

下面示意图是用户级进程各个状态之间地切换示意图:

image-20210619171952351

而对于内核进程状态来说略有差异,其状态定义如下:

image-20210619173748862

进程的属性

pid tgid 的概念

在讲述这两个概念之前,先引入 Linux 中的另外一个概念,也就是线程,在前面提到,进程是资源分配的基本单元,那对于线程来讲,线程是 CPU 调度的最小单位。一个程序中至少有一个进程,一个进程中至少有一个线程。

其实,在 Linux里,无论是进程,还是线程,到了内核里面,都统一叫做任务(Task),并且由一个统一的结构task_struct进行管理。下图是任务管理的一个示意图:

image-20210619205649845

如上图所示的任务列表一样,所有执行的项目有个项目列表,所以也应该有一个链表,将所有的 task_struct串起来,比如应该有如下所示的数据结构

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct list_head     tasks;

对于每一个任务来说,都应该有一个ID,作为这个任务的唯一标识。在task_struct里面涉及到任务ID的,有下面几个:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pid_t pid;
pid_t tpid;
struct task_struct *group_leader;

上述中,pidprocess id,tgidthread group ID,对于任何一个进程,如果只有主线程,那么pid是自己,tgid也是自己,group_leader指向的还是自己。

但是,如果一个进程创建了其他进程,那么就会有所变化了。线程有自己的pidtgid就是进程的主线程pid,group leader 指向的就是进程的主线程。

父进程号(PPID)

任何进程(除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,被创建的进程称为子进程,父进程号无法在用户层修改。父进程的进程号(PID)即为子进程的父进程号(PPID)。

进程组号(PGID)

Linux系统中,进程拥有自己的进程号(PID)和进程组号(PGID),进程组是一个或者多个进程的集合,它们与同一作业相关联,可以接收来自同一终端的各种信号。每个进程组都有唯一的进程组号,进程组号可以在用户层进行修改。

为了更好的说明上述几个“号”之间的区别,给出如下所示的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int i;
    printf("\t pid\t ppid \t pgid\n");
    printf("parent\t%d\t%d\t%d\n",getpid(), getppid(), getpgid(0));

    for (i = 0; i < 2; i++) 
        if (fork() == 0)
            printf("child\t%d\t%d\t%d\n",getpid(), getppid(), getpgid(0));
    return 0;
}

运行代码,得到的结果如下所示:

image-20210619220301951

可以看到,第一行,主进程,pid = pgid,也就是说父进程也就是当前的shell,第二行,子进程,pid 依次增加,pgid=ppid,符合上述的说法

会话

会话,是一个或多个进程组的集合,系统调用函数getsid()用来获取某个进程的会话ID(SID)

比如说,我们通过SSH登陆服务器,就会打开一个控制终端(TTY),这个控制终端就对应一个会话。而我们在终端中运行的命令以及他们的子进程,就构成了一个个进程组,其中,在后台运行的命令,构成的是后台进程组;在前台运行的命令,构成前台进程组。

image-20210619223140086

小结

上述就是本次关于 Linux 进程的一个概述,仅仅是一个概述,没有从很深的层面去分析,而且关于 Linux 进程的内容还有很多,这次只是说了其中一方面,不积硅步,无以至千里,加油呀。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 wenzi嵌入式软件 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在include/linux/sched.h文件中。
233333
2018/09/14
2.5K0
Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数
使学生理解Linux中进程控制块的数据结构,Linux进程的创建、执行、终止、等待以及监控方法。并重点掌握fork函数的使用以及exec系列函数。
猫头虎
2024/04/08
2440
《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数
进程ID及进程间的关系
进程相关的 ID 有多种,除了进程标识 PID 外,还包括:线程组标识 TGID,进程组标识 PGID,回话标识 SID。TGID/PGID/SID 分别是相关线程组长/进程组长/回话 leader 进程的 PID。
mazhen
2023/11/24
8681
进程ID及进程间的关系
Linux进程概念
进程(Process)是计算机中的一个具有独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
利刃大大
2023/04/12
5880
Linux进程概念
Linux进程是如何创建出来的?
在 Linux 中,进程是我们非常熟悉的东东了,哪怕是只写过一天代码的人也都用过它。但是你确定它不是你最熟悉的陌生人?我们今天通过深度剖析进程的创建过程,帮助你提高对进程的理解深度。
开发内功修炼
2022/12/07
2.2K0
Linux进程是如何创建出来的?
一个小实验巩固下进程管理
通过这三篇文章的学习我们知道,无论内核进程还是用户进程,都是可以用task_struct来描述的,那么本篇我们实践下如何通过task_struct字段把系统中所有的进程包含的信息打印出来,比如:属性信息,状态,进程标识符,优先级信息,亲属关系,文件系统信息,内存方面的信息等。
刘盼
2020/05/08
8390
一个小实验巩固下进程管理
Linux进程管理(一)进程数据结构
Linux内核中使用 task_struct 结构来表示一个进程,这个结构体保存了进程的所有信息,所以它非常庞大,在讲解Linux内核的进程管理,我们有必要先分析这个 task_struct 中的各项成员
用户6280468
2022/06/09
1.3K0
Linux进程管理(一)进程数据结构
《Linux内核分析》之分析fork函数对应的系统调用处理过程
xref: /linux-3.18.6/include/linux/sched.h
WindCoder
2018/09/20
1.1K0
《Linux内核分析》之分析fork函数对应的系统调用处理过程
Linux PID 一网打尽
Linux 进程 PID 大家都知道,top命令就可以很容易看到各个进程的 PID, 稍进一步top -H,我们还能够看到各个线程的ID, 即TID。今天我们想深入到Linux Kernel, 看一看在 Kernel里PID的来龙去脉。
扫帚的影子
2020/08/20
3.6K0
Linux PID 一网打尽
Linux进程ID号--Linux进程的管理与调度(三)【转】
Linux 内核使用 task_struct 数据结构来关联所有与进程有关的数据和结构,Linux 内核所有涉及到进程和程序的所有算法都是围绕该数据结构建立的,是内核中最重要的数据结构之一。
233333
2018/09/14
6.2K0
Linux进程ID号--Linux进程的管理与调度(三)【转】
【linux】进程理解
在计算机科学中,进程是操作系统中的一个基本概念,代表了计算机程序的一次执行实例。进程不仅包括正在执行的程序代码,还包括程序的当前活动,包括程序计数器的当前位置、处理器的寄存器和变量的值。简而言之,进程是一个具有自己独立功能的程序在某个数据集上的运行过程,它可以分配和管理资源。
用户11029103
2024/10/12
2530
【linux】进程理解
Linux 线程浅析
关于linux线程 在许多经典的操作系统教科书中, 总是把进程定义为程序的执行实例, 它并不执行什么, 只是维护应用程序所需的各种资源. 而线程则是真正的执行实体. 为了让进程完成一定的工作, 进程必
小小科
2018/05/04
4.5K0
Linux 线程浅析
Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)
exit是c语言的库函数,他最终调用_exit。在此之前,先清洗标准输出的缓存,调用用atexit注册的函数等, 在c语言的main函数中调用return就等价于调用exit。
233333
2018/10/09
6.5K0
【Linux 进程状态】—— 从创建到消亡的全生命周期
书接上回,我们认识了冯诺依曼体系结构,了解了操作系统的概念,以及库函数和系统调用的区别,最后我们讲了进程的概念以及如何在系统中查看存在的进程。 忘记的点这里,光速复习!👉 Linux进程概念 本文将带领大家继续探索进程这座神秘的大山!主要围绕进程状态展开,带领大家进一步的揭开进程的神秘面纱。
换一颗红豆
2025/02/27
2361
【Linux 进程状态】—— 从创建到消亡的全生命周期
LinuxShell命令ps
ps 是 Linux 下显示瞬间进程状态的强大命令,并不动态连续显示进程状态(top 命令则是对进程进行实时监控)。
hotarugali
2022/02/28
8130
Linux下进程的创建过程分析(_do_fork do_fork详解)--Linux进程的管理与调度(八)
Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量级进程,也叫线程,是共享资源的进程)
233333
2018/10/09
2.8K0
Linux下进程的创建过程分析(_do_fork do_fork详解)--Linux进程的管理与调度(八)
Linux进程关系
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! Linux的进程相互之间有一定的关系。比如说,在Linux进程基础中,我们看到,每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构。我们在这里讲解进程组和会话,以便以更加丰富的方式了管理进程。 进程组 (process group) 每个进程都会属于一个进程组(process group),每个进程组中可以包含多个进程。进程组会有一个进程组领导进程 (process gro
Vamei
2018/01/18
1.9K0
Linux进程关系
linux系统的进程管理
本文讲解系统的进程管理相关内容,系统的进程管理是有关系统的所有进程的调度、排序、分配资源、创建、销毁等,是比较重要的内容。
Gnep@97
2024/03/07
3030
linux系统的进程管理
【Linux】深入理解进程管理与高效运用
        进程是正在运行的程序实例,在Linux内核中,进程被称为任务,例如内核线程与用户线程等。
小文要打代码
2025/03/18
2300
linux内核进程创建fork源码解析
    平时写过多进程多线程程序,比如使用linux的系统调用fork创建子进程和glibc中的nptl包里的pthread_create创建线程,甚至在java里使用Thread类创建线程等,虽然使用问题不大,但需要知道底层原理。这次在自己写操作系统的时候,看了一遍linux内核的进程创建过程。算是有了比较深入的理解。
用户4415180
2022/06/23
9K0
linux内核进程创建fork源码解析
推荐阅读
相关推荐
Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
更多 >
LV.1
这个人很懒,什么都没有留下~
交个朋友
加入HAI高性能应用服务器交流群
探索HAI应用新境界 共享实践心得
加入腾讯云技术交流站
洞悉AI新动向 Get大咖技术交流群
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档