系统相关
首页 > 系统相关> > Linux进程概念

Linux进程概念

作者:互联网

目录

基本概念

进程控制块-PCB

进程信息

task_struct内容分类

标示符

进程状态

 细分的进程状态

 程序计数器

上下文信息

内存指针

 IO信息

记账信息

fork创建子进程

fork的使用

 代码模拟

 原理

僵尸进程

僵尸进程的产生

代码模拟

 僵尸进程的危害&如何解决

解决方案

孤儿进程

孤儿进程的产生

代码模拟


基本概念

通俗的观念:程序的一个执行实例,或正在执行的程序。 内核的观点:担当分配系统资源(CPU时间和内存)的实体。

进程控制块-PCB

含义

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

Linux操作系统下的PCB是:task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

进程信息

使用 ps aux 命令可以查看进程,如下:

进程信息也可以进入/proc 系统文件夹查看:

 那么如何查看我们自己写的代码被加载到内存后的进程信息?先来看如下代码:

要查看自己写的代码进程信息,首先要保证代码的运行时间够长,如果运行时间太短,那么查看时进程就已经退出,查看不到了。以上代码中我使用了死循环,将test.c文件进行编译生成test文件运行后,使用命令 ps aux | grep test 就可以查看到进程信息。如果要停止运行,在执行的界面输入:Ctrl+c 就可以结束当前进程。

task_struct内容分类

标示符

描述本进程的唯一标示符(PID),用来区别其他进程。创建任何进程时,它都有一个唯一的ID,称为其进程ID。有两个系统调用函数用于获取进程ID,这些函数是:1.getpid()       2.getppid() 1.getpid()返回值就是当前进程的PID,如下代码中用于验证这点,当代码运行起来后,PID被打印出来,结果与用命令 ps aux | grep test 查看到的结果一致:

 2.getppid()的返回值是当前进程的父进程的PID,与getpid()功能类似。

进程状态

站在CPU的角度,进程状态可以分为:运行、就绪、阻塞。

运行:进程占用CPU,正在使用CPU来执行自己的代码

就绪:进程已经具备运行条件,但是CPU没有分配过来。

阻塞:进程等待某种资源,而不能运行。例如:等待IO输入。

用一幅图来直观的理解:

 细分的进程状态

1.R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。来看如下代码: 代码是死循环,并且什么都不做,当程序运行起来后CPU的占用率非常高,此时当前进程就是运行状态。 2.S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 (interruptible sleep))。如下代码:

3. D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。此状态难以模拟。

4.T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

运行如下代码后,按下Ctrl+z,可以暂停进程,如果想要恢复,按下f+g即可:

 5.t跟踪状态:调试程序的时候可以看到。

如下代码,编译时加上-g选项后,生成可调式的test文件,使用gdb调试,打上断点,让程序运行起来,然后查看进程状态,就可以看得到了。

6.X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。 

7.僵尸状态(Zombies)是一个比较特殊的状态。当进程退出,并且父进程没有读取到子进程退出的返回代码时,就会产生僵尸进程。

 程序计数器

作用:保存程序中即将被执行的下一条指令的地址。

一个进程不一定一直占用CPU资源,当代码没有执行完时,可能会被从CPU当中剥离出来,将CPU资源让其他进程使用,当再一次拥有CPU资源后,程序计数器的作用就体现了,代码可以从上一次中断的位置开始执行。

上下文信息

作用:保存进程执行时处理器的寄存器中的数据。

当进程切换时,保存数据,为下一次在执行做准备。

内存指针

内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。

 IO信息

I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。

记账信息

记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。  

fork创建子进程

fork的使用

fork是用来创建子进程的:

 代码模拟

可以发现,fork()返回给父进程的值是子进程的PID

 原理

1.子进程拷贝父进程的PCB

2.父子进程代码共享

3.数据独有

注意:父子进程在运行的时候是互不干扰的,子进程的代码是从fork()之后开始执行的,不执行fork()语句。主要依靠程序计数器来完成。

僵尸进程

僵尸进程的产生

僵尸体状态(Zombies)是一个比较特殊的状态。当进程退出,并且父进程没有读取到子进程退出的返回代码时,就会产生僵尸进程。

代码模拟

如下代码中,子进程先于父进程退出,父进程并没有回收子进程的退出状态信息,子进程就变成了僵尸进程,状态为僵尸状态(Z+)。

 僵尸进程的危害&如何解决

子进程的PCB一直得不到释放,从而造成了内存泄漏。

解决方案

1.杀死父进程(不推荐)

2.重启操作系统(不推荐)

3.进程等待(属于进程控制章节)

孤儿进程

孤儿进程的产生

父进程先于子进程退出,子进程就称之为"孤儿进程"。

代码模拟

如下代码中,父进程先退出,子进程变成了孤儿进程,后被1号进程领养。

切记:没有孤儿状态。孤儿进程没有危害

标签:fork,状态,僵尸,代码,概念,Linux,进程,CPU
来源: https://blog.csdn.net/Enthusiastic_boy/article/details/123032085