Linux——进程

        之前对进程有一定的概念,但是从操作系统,进程的内存空间,进程的调度,以及一些内部的操作的层面,自己并没有很好地把这些知识点给串起来,形成一个完整的流程。这两天比较系统的学习,所以记录一下。

比喻

        发现计算机很多设计其实都是源于我们人类的行为模式设计的,都是可以在生活中找到类比的例子。

        整个计算机可以比如是一个人,大脑是系统内核+CPU,身体各个部位就是各种工作设备,进程就是我们要做的事情。大脑告诉自己要去做什么事情,这是进程调度。我们在思考一件事情怎么解决,可以理解为CPU处理。比如举个例子,你设了个闹钟,告诉自己11点钟的时候做饭(进程),然后你去看书(进程),当闹钟响的时候,就可以理解是异常中断,大脑(内核)先挂起看书这个进程,这时候大脑需要记录自己看到哪一页哪一行(PCB进程控制块),然后挂起看书这个进程。开始煮饭,找锅,装米,洗米等行为,就是这个做饭进程的处理了,当饭在煮的期间,你自己是不需要在那里无聊等待的,这就是阻塞了(例如一些IO在等待数据到达)。这时候,大脑(内核)又发挥了调度功能,先记录(PCB进程控制块)一下刚只是煮了饭这个步骤,菜还没洗,肉还没切,等待电饭煲的提示中断,再去做菜。然后大脑就会再次调度自己去做其他事情了,比如可以继续看书,也可以看看视频,这个调度算法就完全取决于个人的心情,兴趣爱好了。如果是继续刚刚的事情,那么就会回忆刚刚做什么事情,并且做到了哪一步,就是上下文切换了,恢复现场。看书和做饭这两件事情看起来是同时在进行着,这就是并发的概念。一个时间段内,有多个事情在做,但是一个时间点只能有一件事情占用着你来处理。

        举这个例子,是刚好我要去做饭,哈哈哈,就随手拿来用了。

以下的知识基本是抄录于《深入理解计算机系统(第3版)》

        系统中的每个程序都运行在某个进程的上下文中。上下文是由程序正确运行所需的状态组成的。这个状态包括存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计算器、环境变量以及打开文件描述符的集合。

        每次用户通过向shell输入一个可执行目标文件的名字,运行程序时,shell就会创建一个新的进程,然后在这个新进程的上下文中运行这个可执行目标文件。应用程序也能够创建新进程,然后在这个新进程的上下文中运行它们自己的代码或其他应用程序。

        一个进程和其他进程轮流运行的概念称为多任务

        一个进程执行它的控制流的一部分的每一时间段叫做时间片

Linux——进程_第1张图片

       上下文就是内核重新启动一个被抢占的进程所需的状态。它由一些对象的值组成,包括通用目的寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构,比如描述地址空间的页表、包含有关当前进程信息的进程表,以及包含进程已打开的信息的文件表。

       在内核调度了一个新的进程运行后,它就抢占当前进程,并使用一种称为上下文切换的机制来将控制转移到新的进程,上下文切换1)保存当前进程的上下文,2)回复某个先前被抢占的进程被保存的上下文,3)将控制传递给这个新恢复的进程。

       调用fork(),进程图:

 

Linux——进程_第2张图片

       孤儿进程:如果一个父进程终止了,子进程还在运行。内核会安排init进程成为子进程的养父,init进程的PID为1,是在系统启动时由内核创建,不会终止,是所有进程的祖先。

       僵尸进程:一个终止了但还未被回收的进程。

#include 
#include 

pid_t waitpid(pid_t pid, int *statusp, int options);
//返回:如果成功,则为子进程的PID,如果WHOHANG,则为0,如果其他错误,则为-1


#include 
unsigned int sleep(unsigned int secs);
int pause(void);//让调用函数休眠,知道该进程收到一个信号。

#include 
int execve(const char *filename, const char *argv[], const char *envp[]);
//在当前进程的上下文中加载并运行一个新程序。

 

 

你可能感兴趣的:(Linux)