前言——多进程并发
有OS支持时,会有很多的进程在运行,这些进程都是并发运行的。
什么是并发运行?
就是CPU轮换的执行,当前进程执行了一个短暂的时间片(ms)后,切换执行另一个进程,如此循环往复,由于时间片很短,在宏观上我们会感觉到所有的进程都是在同时运行的,但是在微观上cpu每次只执行某一个进程的指令。
并发 VS 并行
在学习OS的时候,很多人都用过这本教材。这本书中关于并发 VS 并行,是这样解释的:
并发:宏观上是并行,微观上是分时交替执行
并行:宏观上是并行,微观上也是并行。
对于单核CPU,只存在并发。
对于多核CPU,不同的cpu核可以同时独立的执行不同的进程,并发与并行是同时存在的。
PID
什么是PID
基于OS运行的进程有很多,OS为了能够更好地管理进程,为每个进程分配了一个唯一的编号(非负整数),这个编号就是PID,P就是process——进程的意思。这记好比公安局给每个人分配了一个唯一的身份证号(ID)是一样的。
如果当前进程结束了,这个PID可以被可以被重复使用,但是所有“活着”的进程,它们的进程ID一定都是唯一的。因为ID的唯一性,当我们想创建一个名字唯一的文件时,往往可以在文件名中加入PID,这样就能保证文件名的唯一性。
PID放在那里
进程在运行的过程中,OS会去管理进程,这就涉及到很多的管理信息,OS(Linux)为了管理进程,会为每一个进程创建一个task_struct结构体变量,里面放了各种的该进程的管理信息,比如文件描述符表,PID。
如何获取PID
原型
#include <sys/types.h> #include <unistd.h> pid_t getpid(void); pid_t getppid(void); uid_t getuid(void); gid_t getgid(void);
功能
getpid函数:获取调用该函数进程的进程ID。
getppid函数:获取调用该函数进程的父进程ID,第一个P是parent,第二个process。
getuid函数:获取调用该函数进程的用户ID。在什么用户下运行的该进程,得到的就是该用户的用户ID,查看/etc/passed文件,可以找到该UID对应的用户名。
getgid函数:获取用户组的ID,也就是调用该函数的那个进程,它的用户所在用户组的组ID。
参数
无
返回值
返回各种ID值,不会调用失败,永远都是成功的。
三大主要进程
三大主要进程指的是PID=0,1,2的三个进程。0、1、2这个三个进程,是OS启动起来后会一直默默运行的进程,直到关机OS结束运行,尽管我们总是忽略它们的存在,但是它们确非常的重要。
PID == 0 的进程
这个进程被称为调度进程,功能是实现进程间的调度和切换,该进程根据调度算法,该进程会让CPU轮换的执行所有的进程。
进程切换怎么实现的?
当pc指向不同的进程时,cpu就去执行不同的进程,这样就能实现切换。
这个进程怎么来的?
这个进程就是有OS演变来的,OS启动起来后,最后有一部分代码会持续的运行,这个就是PID==0的进程。由于这个进程是OS的一部分,凡是由OS代码演变来的进程,都称之为系统进程。
PID == 1的进程
作用
①初始化。这个进程被称为init进程,这个进程的作用是,他会去读取各种各样的系统文件,使用文件中的数据来初始化OS的启动,让我们的OS进入多用户状态,也就是让OS支持多用户的登录。
②托管孤儿进程。
③原始父进程
这个进程怎么运行起来的
这个进程不是OS演变来的,也就是说这个进程的代码不属于OS的代码,这个进程是一个独立的程序,程序代码放在了/sbin/init下,当OS启动起来后,OS回去执行init程序,将它的代码加载到内存,这个进程就运行起来了。
PID == 2的进程
作用
页精灵进程,专门负责虚拟内存的请页操作。
疑问:什么精灵进程?
精灵进程也叫守护进程
疑问:怎么理解换页操作?
我们说当OS支持虚拟内存机制时,加载应用程序到内存时,并不会进行完整的代码拷贝,只会拷贝当前要运行的那部分代码,当这部分代码运行完毕后,会再拷贝另一部分需要运行的代码到内存中,拷贝时是按照一页一页来操作的,每一页大概4096字节,这就是换页操作。
这个进程怎么运行起来的
与PID=0的调度进程一样,也是一个系统进程,PID=2这个进程的代码属于OS的一部分。