Linux进程概念

Linux进程

一.冯诺依曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。

截至目前,我们所认识的计算机,都是由一个个硬件组件而成的。

  • 输入设备:键盘、鼠标、摄像头、麦克风、网卡、硬盘
  • 中央处理去(cpu):含有运算器与控制器等
  • 输出设备:显示器、声卡、喇叭、网卡、硬盘

 

运算器 + 控制器 + 其他 = CPU           快                   负责计算           cpu很笨,只能被动接受别人的指令,别人的数据     cpu必须先识别指令,它具有自己的指令集

存储器   内存                                     较快                 临时存储           cpu在读取和写入的时候,在数据层面和内存打交道。为什么?提高整机效率,cpu和外设的速度差距太大,加入内存缓冲

外设(输入设备,输出设备)                 较慢                 永久存储            我们将数据从外设到内存,从内存到外设,是IO的过程  INPUT/OUTPUT 

 

由此我们可以得出结论,在数据层面

  1. CPU不和外设直接打交道,和内存直接打交道

  2.所有的外设,有数据需要载入,只能载入到内存中。内存写出,也一定是写到外设中

  CPU不和外设直接沟通,只和内存直接打交道!

例如程序要运行必须加载到内存?为什么要加载?

  CPU要执行我的代码访问我的数据,只能从内存中读取(体系结构体规定!)

二.操作系统(Operator System)

操作系统是一个进行软硬件资源管理的软件

概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括: 

  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库,shell程序等等)

设计OS的目的

  • 与硬件交互,管理所有的软硬件资源
  • 为用户程序(应用程序)提供一个良好的(稳定的,高效的,安全的)执行环境

如何理解 "管理"

管理的本质:是对数据做管理!!!

            

总结

计算机管理硬件

  • 描述起来,用struct结构体
  • 组织起来,用链表或其他高效的数据结构

系统调用和库函数概念

  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。例如c语言中的部分函数本质上也是进行系统调用

三.进程

基本概念

  课本概念:程序的一个执行实例,正在执行的程序等

  内核观点:担当分配系统资源(CPU时间,内存)的实体。

描述进程-PCB

  进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。

  课本上称之为PCB(process control block),Linux操作系统下的PCB是task_struct

task_struct-PCB的一种

  • 在Linux中描述进程的结构体叫做task_struct。
  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

task_ struct内容分类

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

组织进程

  可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

查看进程

1.进程的信息可以通过/proc 系统文件夹查看

蓝色的数字就是pid。在系统中,进程也是文件,可以进入进程文件查看详细信息

在进程运行时删除程序,进程不会退出。此时,exe->那一行会变红闪烁

2.使用topps这些用户级工具来获取

下述图片为top

可以使用ps axj | head -1 && ps axj | grep 'filename'来查询进程状态

上述图片head -1是显示表头。查自己程序的产生的进程时,第二个是查所需程序进程产生的进程

通过系统调用创建进程-fork初识

fork有两个返回值

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

查看代码
 #include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
  pid_t id = fork();
  if(id == 0)
  while(1)
  {
    printf("我是子进程!pid:%d,ppid:%d\n",getpid(), getppid());
    sleep(1);
  }
  else if(id > 0)
  {
    while(1)
  {
    printf("我是父进程!pid:%d,ppid:%d\n",getpid(), getppid());
    sleep(5);
  }
  }
  return 0;
}

四.进程状态

进程的状态

程的状态大概为

运行     新建    就绪   挂起   阻塞    等待    停止    挂机   死亡  ........

进程如此多的状态都是未来满足不同场景运行的!

  1. 一个CPU一个运行队列
  2. 让进程进入队列,本质:将该进程的task_struct结构体对象放在运行队列中!
  3. 进程PCB在runqueue,就是R,不是这个进程正在运行才是运行状态
  4. 不要只意味,你的进程只会等待(占用)CPU资源,你的进程,也可能随时随地要外设资源!!!
  5. 所谓的进程不同的状态,本质是进程在不同的队列中,等待某种资源!

  1. 阻塞 VS 挂起: 阻塞不一定挂起,挂起一定阻塞
  2. 除了运行状态(概率特别小),其他状态均有可能挂起

Linux内核源代码

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。 

下面的状态在kernel源代码里定义:

/*
 * 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 */
 };
  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))可以被终止。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束,在该状态无法被操作系统杀掉,只能通过断电和进程醒来杀死。
  • T停止状态(stopped): 可以通过发送 19) SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 18)SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

 

我们可以看到进程目前的状态为S+,但是我们的程序一直在朝外打印东西

这其实是由于外设打印到显示器上特别慢,等待显示器就绪,要花很长的时间,99%的时间都是在等待IO就绪,1%再执行打印代码

进程状态查看

ps axj | grep '进程名' 
ps axj |head -1 && ps axj | grep '进程名' #为了看起来更方便,我们给他加上表头 

进程状态控制

语法kill [选项] PID

可以通过kill -l来查找选项

我们实践暂停一下进程

               

将其恢复,却发现他的加号已经消失了

带加号表示前台进程,没有加号表示后台进程,后台进程无法使用Ctrl c终止,只能使用 kill -9 PID的形式终止

僵尸进程(Zombie Process)

概念

  •  僵尸进程是指一个子进程已经结束(即已经运行完毕),但是其父进程尚未通过 wait 或 waitpid 等系统调用回收其结束状态(也就是它的资源信息,包括 PID 等进程标识符)时的状态。这个时候,子进程就变成了僵尸进程。
  • 例如,假设有一个父进程 Fork 了一个子进程去执行一个简单的任务(如计算一个简单的数学公式)。子进程完成后,它需要向父进程回报自己的状态。但如果父进程没有使用 wait 或 waitpid 等调用去获取子进程的状态,那么子进程就会变成僵尸进程。即使子进程的程序代码已经完全运行结束,它还占用着系统中一些资源,如进程表项信息等。

特点

  • 资源占用:
    ◦ 僵尸进程的 task_struct(PCB)会一直保留在内存中,包含进程的退出状态、资源使用统计等信息。
    ◦ 内核需要维护这些数据以供父进程查询,因此僵尸进程的 PID、退出码、运行时间 等基本信息不会被释放。
    ◦ 虽然僵尸进程已不执行代码,但其占用的内核资源(如 PCB 结构体)会导致内存泄漏。

孤儿进程(Orphan Process)

概念

  •  孤儿进程是指父进程在子进程之前结束,而子进程仍在运行的情况。子进程因为父进程的消亡而失去了原本的 “赞助人”,成为孤儿进程。在这种情况下,孤儿进程会被操作系统收养,通常由 init 进程(在类 Unix 系统中,PID 为 1 的进程)接管,成为 init 的子进程。
  • 举个例子,如果父进程启动了一个子进程来执行某个长期运行的任务(如一个后台数据处理任务),然后父进程自己因为某种原因(例如出现致命错误,或者被用户 kill 掉)结束了。此时子进程就成了孤儿进程。不过,init 会成为它的新的父进程,接管它的运行。

特点

  • 它们还在执行任务。孤儿进程本身可能仍然在执行有用的系统任务。比如,一个父进程 fork 出一个子进程去做一个复杂的计算任务,父进程因为某些意外(比如被系统强制终止)结束了,而子进程还在进行计算。这时候子进程成为孤儿进程,但它的计算任务依然在继续进行。
  • 如果是前台进程创建的子进程,如果孤儿了,会自动变成后台进程

五.进程优先级

基本概念

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

查看系统进程

在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:

我们很容易注意到其中的几个重要信息,有下:

  • UID(User ID):它是进程所有者的用户 ID。在系统中,每个用户都有一个唯一的用户 ID,用于标识用户身份。
  • PID(Process ID):这是进程的唯一标识符。每当系统创建一个新进程时,都会为它分配一个唯一的 PID。PID 的作用就像人的身份证号码一样,用于在系统中唯一地识别一个进程。
  • PPID(Parent Process ID):它表示进程的父进程 ID。在操作系统中,一个进程可以创建新的进程,创建者被称为父进程,被创建者是子进程。PPID 就是用来标识子进程的父进程的 PID。
  • PRI(Priority):进程优先级。它用于确定进程在 CPU 调度中的优先顺序。操作系统会根据 PRI 值来分配 CPU 时间,优先级高的进程会更优先地获得 CPU 资源。其值越小越早被执行
  • NI(Nice Value):它与进程优先级有关,用于调整进程的优先级。Nice 值的范围通常是从 - 20 到 19。值越小,进程的优先级越高;值越大,优先级越低。用户可以通过修改 Nice 值来调整进程  的优先级,以平衡不同进程对系统资源的使用。

查看进程优先级的命令

ps -al #显示所有用户的所有进程(包括与其他用户的进程),并且以详细格式列出。

ps -l #显示当前终端的进程和没有控制终端的进程,并以详细格式列出。

上述两种方式都可以查进程的优先级

用top命令更改已存在进程的nice:

  • top  (修改NI,此操作需要提权或使用root账号才能修改)
  • 进入top后按“r”–>输入进程PID–>输入nice值

Nice 值的范围通常是从 - 20 到 19。值越小,进程的优先级越高;值越大,优先级越低。用户可以通过修改 Nice 值来调整进程 的优先级,以平衡不同进程对系统资源的使用。

使用top设置优先级重复设置不会叠加,每一次设置都是重新从80进行加减nice值。

其他概念

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

 

posted @   chonbw  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示