Linux 进程

目录

操作系统

进程

进程概念

进程的描述--PCB

task_ struct内容分类

进程的组织

查看进程

通过系统调用接口获取进程标志符(进程ID)

进程状态

进程优先级


操作系统

引言: 在了解进程之前, 先简单了解一下操作系统 .

操作系统(Operating System), 简称OS 是配置在计算机硬件上的第一层软件, 是对硬件系统的首次扩充 . 其主要作用是管理好这些设备,  提高它们的利用率和系统的吞吐量,  并为用户和应用程序提供一写简单的接口, 便于用户使用.  事实上, OS 已经成为现代计算机系统,  多处理机系统,  计算机网络系统中必须配置的系统软件 .

包含 :
         内核 : 进程管理,内存管理,文件管理,驱动管理
         其他程序 :  函数库, Shell等

作用 :
         对于用户 :
为用户以及用户的应用程序提供良好的环境
         对于硬件 : 管理所有的软硬件资源,  以提高系统的资源利用率

操作系统就是进程的管理者

 

 


进程

引言

说到进程 . 离不开计算机或操作系统的发展过程. 简单的说一下.

在计算机高度发达的今天, 我们很难想象以前的计算机是什么样的. 

最初的时候, 计算机只能接受一些特定的指令, 用户输入一个指令, 计算机就做一个操作. 当用户在思考或者输入数据时, 计算机就在等待. 显然这样效率很低下, 因为很多时候,计算机处于等待用户输入的状态 .

为了解决这个问题, 批处理操作系统诞生了. 用户可以将需要执行的多个程序写在磁带上(很难想象一个计算机用的是磁带, 更夸张的是更早的时候使用纸带上面打孔), 然后交由计算机去读取并逐个地执行这些程序, 并将输出结果写到另一个磁带上.

但批处理系统仍然存在一个很大的问题, 当第一个程序在进行I/O(数据输入输出)操作时, 另一个程序只能干等着, 但此时CPU也闲着, 第二个程序心想, 你这不是占着x坑不拉x嘛, 白白浪费可爱的CPU. 人们就想能不能在第一个程序I/O的过程中, 让第二个程序开始运行, 当第一个程序I/O完毕后, 暂停第二个程序的运行, 再恢复第一个程序的运行呢?

但还有一个问题摆在面前, 在原来的计算机中, 每次都只有一个程序的运行数据在内存中, 而上面的设想需要内存中装入多个程序, 又该如何处理呢? 内存中的数据谁是谁的又该如何辨别, 如何实现前面说的暂停恢复呢?

这个时候人们就引入了进程的概念, 用进程来描述一个程序, 每个进程对应一定的内存地址空间, 并且只能使用它自己的内存空间, 各个进程间互不干扰. 并且进程保存了程序每个时刻的运行状态, 这样就为进程切换提供了可能. 当进程暂停时,它会保存当前进程的状态 (比如进程标识、进程的使用的资源等) , 在下一次重新切换回来时, 便根据之前保存的状态进行恢复, 然后继续执行.

人们把CPU运行间划分成若干个时间段, 再将时间段分配给各个进程执行. 这样, 在一个时间段内某个进程的代码运行时, 其它线程处于挂起状. 当时间片较小, CPU轮转非常快时, 宏观上有多个进程被同时执行的效果. 这种方式我们称之为并发(Concurrent)

人们在设计多道程序OS时,引入进程的概念,从而解决了单处理机环境下程序并发执行的问题, 提高系统资源的利用率和系统吞吐量. 此后,进程一直作为资源分配和独立调度运行的基本单位 . 

进程概念

程序是一个可执行的二进制文件,  存放在外存(硬盘, U盘 , 光盘等)中,  当程序执行时, 加载到内存中 . 就成为了进程 .

进程 是操作系统进行资源分配和独立调度的一个基本单位, 解决了操作系统中程序并发执行的问题, 提高系统资源的利用率和系统

吞吐量 .

可是问题来了, 我们说了半天进程是什么, 可是操作系统可不是个人,  它怎么会理解这些文字概念呢? 更别说来管理进程了                                                                    

 

举个栗子,  我们在学校上学, 被学校的约束与管理.  那么学校这么多学生,  学校的管理者们又怎样管理学生呢?  总不能让管理

人员把每个人都记在心里,  这显然不可能.  其实我们都知道, 学校给每个学生一个都有一份学籍档案 .  对学生的管理, 就是对其学

籍档案的管理.  例如, 开除一个学生,  怎样才算开除呢?  开除学籍才是开除 .

学校将不同种类(年级, 学院, 专业等)学生的学籍档案统计在一起, 更加方便学校进行统一管理. 例如,  有一个竞赛,  老师要选择一

位同学参加,  就可以直接在同专业学生中比较成绩, 谁成绩较好谁去.    这就是一个先描述,  再组织的过程  先将学生描述为具体的

学籍档案,  再对档案进行组织,  然后再管理.那么操作系统管理进程也是类似于这样.  操作系统先给进程一个描述(相当于学籍档

案), 再进行组织管理 .

那么,  操作系统能听懂什么呢 ? 其实,  操作系统只认识计算机中的二进制数据,  那么就用数据来描述进程. 让操作系统对其了如指

掌.

进程的描述--PCB

操作系统给每一个进程都分配了一个专门的数据结构, 称之为进程控制块 ( Process Control Block ), 即 PCB. 

在Linux下这个PCB的数据结构式是 task_struct (结构体) , 在进程创建时, 会被加载到内存中.

PCB描述进程对于操作系统, 就相当于学籍档案对于学校管理者.  学籍档案里记录着我们的基本信息, PCB里也保存着进程的息.

学校可以通过学籍档案管理我们, 同样, 操作系统也靠着PCB来管理着进程, , 例如,  创建进程, 就是创建PCB .

在Liinux下当然就是创建一个task_struct ,  那么Linux 中的task_struct 到底保存的是进程的什么信息呢?


task_ struct内容分类

  • 标示符: 描述进程的唯一标示,用来区别其他进程(也就是进程号, 也叫PID)
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级 . 
  • 程序计数器: 程序中即将被执行的下一条指令的地址 . 
  • 内存指针:  包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针 .
  • 上下文数据: 进程执行时处理器的寄存器中的数据 .
  • I/O状态信息: 包括显示的I/O请求, 分配给进程的I/O设备和被进程使用的文件列表 .
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

操作系统通过PCB , 在Linux中也就是task_struct中的内存指针能够找到内存中运行的程序代码以及数据, 并且通过上下文数据来

保存程序调度切换时正在处理的数据, 并且通过程序计数器保存进程切换时即将执行的下一步指令, 等等. 通过这些描述信息来控

制进程的运行, 所以就可以说,  对操作系统而言,  进程就是PCB.

那么有了PCB的操作系统具体是如何管理进程的呢 ?

进程的组织

Linux下所有在内存中运行的进程的PCB, 也就是task_struct, 是以双向循环链表 ( 也可叫做, 运行队列 ) 的形式在内核中. 

这样,  Linux下进程被描述为task_struct, 在内核中被组织成一个双向循环链表,  这样, 操作系统就可类似于学校管理学生一样管理

进程了.

查看进程

方法1 : 在根目录下有一个叫 proc 的目录, 其中就保存着进程的相关信息, 如下

方法2 : ps / top 命令

ps

ps命令用于报告当前系统的进程状态。可以搭配 kill 指令随时中断、删除不必要的程序。ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的。

通常用 ps -aux 或 ps -ef  通常搭配 grep 使用

TEST.c如下, gcc TEST.c  -o TEST  编译成为可执行文件TEST . 

这个进程会进入一个死循环,  所以会一直运行着, 我们用ps -aux 搭配 grep 可以找到TEST 进程的信息

top

top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具。通过top

命令所提供的互动式界面, 按q 退出 .

 

通过系统调用接口获取进程标志符(进程ID)

进程标识 : PID         系统调用接口 :  getpid()
父进程标识: PPID    系统调用接口 :  getppid() 

//Test2.c
#include<stdio.h>
#include<unistd.h>
int main(){
    printf("pid: %d\n", getpid());
    printf("ppid: %d\n", getppid());
    return 0;
}


进程状态

还是那个例子, 在学校中,  学生有着不同的状态,  比如说, 休学, 请假, 毕业, 退学,  学业警告等各种表示学生学习生活状态的信息 .

进程就像学校里的学生一样, 也有着不同的状态. 我们来看内核中对linux下进程状态的定义

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
    "R (running)", /* 0 */         /*[重点]*/
    "S (sleeping)", /* 1 */        /*[重点]*/
    "D (disk sleep)", /* 2 */
    "T (stopped)", /* 4 */         /*[重点]*/
    "t (tracing stop)", /* 8 */
    "X (dead)", /* 16 */
    "Z (zombie)", /* 32 */         /*[重点]*/
};

详细在另一篇博客中,

戳链接( ̄︶ ̄)↗https://blog.csdn.net/qq_41071068/article/details/103231310


进程优先级

详细在另一篇博客中,

戳链接( ̄︶ ̄)↗https://blog.csdn.net/qq_41071068/article/details/103248463

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值