00. 目录

文章目录

  • 00. 目录
  • 01. 进程概述
  • 02. 进程状态
  • 03. 进程控制块
  • 04. 进程号
  • 05. 进程号相关函数
  • 06. 案例实战
  • 07. 附录

01. 进程概述

我们平时写的 C 语言代码,通过编译器编译,最终它会成为一个可执行程序,当这个可执行程序运行起来后(没有结束之前),它就成为了一个进程。

程序是存放在存储介质上的一个可执行文件,而进程是程序执行的过程。进程的状态是变化的,其包括进程的创建、调度和消亡。程序是静态的,进程是动态的。

在 Linux 系统中,操作系统是通过进程去完成一个一个的任务,进程是管理事务的基本单元。进程拥有自己独立的处理环境(如:当前需要用到哪些环境变量,程序运行的目录在哪,当前是哪个用户在运行此程序等)和系统资源(如:处理器 CPU 占用率、存储器、I/O设备、数据、程序)。我们可以这么理解,公司相当于操作系统,部门相当于进程,公司通过部门来管理(系统通过进程管理),对于各个部门,每个部门有各自的资源,如人员、电脑设备、打印机等。

02. 进程状态

我们现在的电脑基本上都是多任务,我们聊着 QQ 的时候,同时可以看着视频,这里相当于 QQ 和视频两个程序同时运行着(两个进程)。早期的时候,电脑的 CPU 是单核的(单核理论上只运行操作一个任务),那它是如何做到多任务的呢?这就涉及到进程的调度策略。现在给大家举这么一个例子,有 A,B,C 三个进程,在我们单 CPU 的情况下,每一个时刻只有一个进程在运行,如果 A 运行完,B 运行,B 运行完,C 运行,C 运行完,A 运行,而 CPU 的运算速度足够快,A 两次运行时间间隔足够短,从宏观上就我们就看到 A,B,C 好像同时运行,这就是实现单 CPU 运行多个任务的核心原理,通过时间片轮询调度策略实现多任务。

从上面的例子,我们可以得知,对于 A 进程而言,有时候在运行,有时候没有运行,两个状态不一样,所以,进程是有状态的,同时,状态是可以相互进行转换的,从执行的状态转换为不执行的状态,这里,我们可以把进程运行的整个生命周期简单划分为三种状态(实际上不指这三种状态):就绪态、执行态、等待态

就绪态:

进程已经具备执行的一切条件,正在等待分配 CPU 的处理时间。

执行态:

该进程正在占用 CPU 运行。

等待态:

进程因不具备某些执行条件而暂时无法继续执行的状态。

这里需要注意,就绪态和等待态都是不执行,但它们是有区别的,就绪态是指满足条件,时间没到,等待态是不满足条件。

同样的,进程的这三种状态可以相互转换:

为了让大家更好地这三种状态的转换,给大家举一个买火车票的例子

Tom匆忙地赶去火车站买火车票,太着急了,到了售票厅才发现忘记带身份证,这时候,就算Tom排队也没用,因为 Tom不具备买票的条件(没带身份证),这时候的 Tom属于等待态。

Tom给它对象打电话,让她把身份证带过来,等会,身份证送到了,这时候,Tom可以去排队买票了,只是时间到,Tom就可以买票了,这时,Tom属于就绪态。而这过程是由等待态转换到就绪态。

等了 10 分钟,终于到 Tom了,Tom开始买票,这时候, Tom属于执行态。而这过程是由就绪态转换为执行态。

而在买票的过程中,Tom的对象打电话给他,让 Tom也帮她买一张火车票,但是, Tom没有她对象的身份证,接着,Tom继续等他对象送身份证,这时候,Tom由执行态转换为等待态。

假如是这么一种情况,Tom买火车票是给公司的同事买的(需要买 100 多张票),在买着票的过程中(执行态),后面还有很多人在排队,后面排队的人肯定不爽,这时售票员就说,20分钟后,如果你还没处理完,请你到后面排队。结果,Tom花了 20 分钟还是没有处理完,于是,乖乖地到后面重新排队,这时候,Tom由执行态转换为就绪态。

03. 进程控制块

对于操作系统而言,它需要控制很多进程,同时,每个进程都有不同的状态,系统如何知道 A 执行完到 B 执行而不是 C?系统如何协调控制进程呢?

当我们运行一个程序使它成为一个进程时,系统会开辟一段内存空间存放与此进程相关的数据信息,而这个数据信息是通过结构体( task_struct,打开 /usr/src/linux-headers-4.15.0-30/include/linux/sched.h可以找到 task_struct 的定义 )来存放,我们把这个存放进程相关数据信息的结构体称为进程控制块。操作系统就是通过这个进程控制块来操作控制进程。

进程控制块是操作系统中最重要的记录型数据结构。进程控制块记录了用于描述进程进展情况及控制进程运行所需的全部信息,它是进程存在的唯一标志。进程控制块里有很多信息,其中比较重要的是进程号,至于其他的一些信息我们不在这详细讨论。

04. 进程号

每个进程都由一个进程号来标识,其类型为 pid_t(无符号整型),进程号的范围:0~32767。进程号总是唯一的,但进程号可以重用。当一个进程终止后,其进程号就可以再次使用。

系统允许一个进程创建新进程,新进程即为子进程,子进程还可以创建新的子进程,形成进程树结构模型。整个 Linux 系统的所有进程也是一个树形结构。树根是系统自动构造的,即在内核态下执行的 0 号进程,它是所有进程的祖先。进程号为 0 的进程通常是调度进程,常被称为交换进程( swapper )。由 0 号进程创建 1 号进程(内核态),1 号负责执行内核的部分初始化工作及进行系统配置,并创建若干个用于高速缓存和虚拟主存管理的内核线程。随后,1 号进程调用 execve() 运行可执行程序 init,并演变成用户态 1 号进程,即 init 进程。

所以,在 Linux 下面所有的进程都由 init 进程直接或者间接创建。

进程号(PID)

标识进程的一个非负整型数。

父进程号(PPID)

任何进程( 除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。如,A 进程创建了 B 进程,A 的进程号就是 B 进程的父进程号。

进程组号(PGID)

进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID) 。这个过程有点类似于 QQ 群,组相当于 QQ 群,各个进程相当于各个好友,把各个好友都拉入这个 QQ 群里,主要是方便管理,特别是通知某些事时,只要在群里吼一声,所有人都收到,简单粗暴。但是,这个进程组号和 QQ 群号是有点区别的,默认的情况下,当前的进程号会当做当前的进程组号。

Linux 操作系统提供了三个获得进程号的函数 getpid()、getppid()、getpgid()

05. 进程号相关函数

getpid函数

#include <sys/types.h>
#include <unistd.h>pid_t getpid(void);
功能:获取本进程号(PID)
参数:无
返回值:本进程号

getppid函数

pid_t getppid(void);
功能:获取调用此函数的进程的父进程号(PPID)
参数:无
返回值:调用此函数的进程的父进程号(PPID)

getpgid函数

pid_t getpgid(pid_t pid);
功能:获取进程组号(PGID)
参数:pid:进程号
返回值:参数为 0 时返回当前进程组号,否则返回参数指定的进程的进程组号

06. 案例实战

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>//pid_t ---> int
//pid_t getpid(void);
//pid_t getppid(void);
//
//uid_t getuid(void);
//uid_t geteuid(void);//gid_t getgid(void);
//gid_t getegid(void);int main(void)
{//获取当前进程的进程号printf("getpid: %d\n", getpid());   //获取当前进程的父进程号printf("getppid: %d\n", getppid());//实际用户IDprintf("getuid: %d\n", getuid());//有效的用户IDprintf("geteuid: %d\n", geteuid());//实际组IDprintf("getgid: %d\n", getgid());//有效组IDprintf("getegid: %d\n", getegid());return 0;
}

编译和测试结果

deng@itcast:/mnt/hgfs/LinuxHome/code/4sys/3rd/code$ gcc 20getpid.c
deng@itcast:/mnt/hgfs/LinuxHome/code/4sys/3rd/code$ ./a.out
getpid: 7986
getppid: 7436
getuid: 1000
geteuid: 1000
getgid: 1000
getegid: 1000
deng@itcast:/mnt/hgfs/LinuxHome/code/4sys/3rd/code$

07. 附录

7.1 下载代码:

7.2 参考博客:【Linux系统编程】进程介绍

【Linux系统编程】进程概述和进程号相关推荐

  1. Linux系统编程(三)进程间的通信

    Linux系统编程(三)进程间的通信 一.为什么需要进程之间的通信(IPC)? 二.管道 1.概念 2.特质 3.原理 4.局限性 5.代码 2.读入数据 三.共享存储映射 注意事项 父子进程通信 一 ...

  2. linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数

    linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...

  3. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

  4. 初始Linux—Linux系统编程第三节——初始进程

    目录 冯 · 诺依曼体系结构 操作系统:Operator System(OS) 进程的基本概念 进程标识符 通过系统调用创建进程-fork初识 进程状态 僵尸进程 孤儿进程 进程优先级 环境变量 和环 ...

  5. 【Linux系统编程】浅谈进程地址空间与虚拟存储空间

    早期的内存分配机制 在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址.当计算机同时运行多个程序时,必须保证这些 ...

  6. 【Linux系统编程】线程与进程的比较

    在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体. 为了让进程完成一定的工作,进程必须至少包含一个线程. 进程, ...

  7. Linux系统编程第六节——进程的替换(execl、exelp、execle、execv、execvp、execve)

    本节的内容很简单,就是研究一下进程替换的有关内容即可. 也不存在什么导图了,因为就这一个知识点. 先说一下什么叫进程替换. 说白了,就是一个进程还没有运行完,被掉包了,被换掉了,换成了执行另外一个进程 ...

  8. linux系统编程 mmap无亲缘关系进程通信

    在无亲缘关系的前提下,两个进程必须是对同一个文件进行创建映射区操作. 对映射区进行写操作: 1 #include<stdio.h>2 #include<string.h>3 # ...

  9. Linux系统编程总结

    day2 vim的三种工作模式 命令模式 vi hello.c zz 保存退出 2.编辑模式 i a o s (有大写)可以写东西 3.末行模式: 文本和末行模式不能直接切换 要切换回命令模式 再到末 ...

  10. linux有名管道数据异常,Linux系统编程—有名管道

    ▋****1. 管道的概念 管道,又名「无名管理」,或「匿名管道」,管道是一种非常基本,也是使用非常频繁的IPC方式. 1.1 管道本质 管道的本质也是一种文件,不过是伪文件,实际上是一块内核缓冲区, ...

最新文章

  1. 使用Keil MDK以及标准外设库创建STM32工程
  2. 华硕笔记本电池0%充不进电_笔记本电脑电池充不进电如何解决【解决方法】
  3. Python教程:zip 函数的用法
  4. git 学习之基础知识
  5. 识别物体是否存在_【科学实践Vol.1】带你玩转“人脸识别”
  6. mpython掌控板作品_第1课 Arduino micro:bit 掌控板 创客教育常用的3类主控板
  7. 错误的日志可能会导致疯狂;好日志可能会成为魔杖
  8. LAMP下http跳转到 https
  9. VC6.0+ddk+DriverStudio3.2安装与配置
  10. SQLServer 2000个人版下载
  11. 大漠插件最新版7.2123
  12. 你不可不知的铠装光缆常识
  13. 坤坤音效键盘(Python实现)
  14. linux afs3服务,AFS配置3
  15. 典型IO模型----阻塞IO,非阻塞IO,信号驱动IO,异步IO
  16. 达人评测 r7 7735h和i7 13700h选哪个 锐龙r77735h和酷睿i713700h差距
  17. substrate介绍
  18. 【技术点】数据结构--B树系列(四)
  19. 关于数据清洗的常见方式
  20. 空调系统的PUE值计算

热门文章

  1. 【反射的使用】java反射的复习
  2. 二次开发是什么意思_什么是框架?为什么要使用框架?我告诉你理由哦!
  3. C语言程序练习-L1-017 到底有多二 (15分)
  4. python3 面向对象编程_Python3基础-面向对象编程
  5. Java黑皮书课后题第10章:10.4(MyPoint类)设计一个名为MyPoint的类,代表一个以x坐标和y坐标表示的点
  6. Java黑皮书课后题第4章:*4.3(几何:估算面积)应用4.1节图中以下地点的GPS位置:Georgia州的Atlanta……计算被这四个城市所围起来的区域面积
  7. [给 ASP.NET初学者的话]挑书与买书,买适合自己的书
  8. 【Java学习笔记之二十八】深入了解Java8新特性
  9. 修改 wordpress 后台管理员登录地址
  10. Android获取状态栏、标题栏、屏幕高度