目录
基本概念
通俗的观念:程序的一个执行实例,或正在执行的程序。 内核的观点:担当分配系统资源(CPU时间和内存)的实体。进程控制块-PCB
含义
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。 Linux中的PCBLinux操作系统下的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号进程领养。
切记:没有孤儿状态。孤儿进程没有危害