深入理解计算机操作系统——第8章:进程控制
8.4 进程控制
8.4.1 获取进程ID
(1)pid_t getpid(void)和pid_t gettpid(void)函数,其中返回的是pid_t整数值
(2)pid_t在types.h文件中被定义
8.4.2 创建和终止进程
进程的三种状态:
(1)运行:进程要么在CPU运行,要么在等待被调度(且最终被调度)
(2)停止:进程的执行被挂起,且不会被调度。
(3)终止:进程永远的停止了。可能是:收到一个信号,该信号的默认行为是终止进程,从主程序返回,调用exit函数
fork()函数
(1)父进程通过调用fork()函数创建一个子进程。 pid_t fork(void)
(2)这个函数在子进程中返回0.在父进程中返回子进程的ID。
(3)子进程会得到与父进程虚拟地址空间相同(但独立的)一个地址空间
(4)子进程还得到与父进程相同的打开文件描述符的拷贝。
fork函数注意的地方:
(1)调用一次返回两次,在父进程中返回子进程的ID,在子进程中返回0值。
(2)并发执行:父进程和子进程是并发的执行的进程,所有不要做任何的假设(比如哪个先执行)。
(3)相同但是独立的地址空间:相同的用户栈,相同的本地变量,相同的堆,相同的全局变量,以及相同的代码。
(4)因为得到相同的打开的文件描述符,所以父子进程的输出都会显示在屏幕上。
8.4.3 回收子进程
(1)当一个进程由于某种原因终止时,内核并不会马上把它从系统中清除,而是保存为一种终止的状态,等待父进程回收
(2)当父进程回收子进程时,系统将子进程的状态信息传递给父进程,然后彻底清除这个进程
(3)在进程已经终止而等待回收的期间称为僵死进程
waitpid函数:
pid_t waitpid(pid_t pid,int *status,int options)
一个进程可以通过调用这个函数来等待它的子进程的终止或停止。
第一个参数,pid>0时为等待的子进程ID,=-1时为等待所有的子进程
第二个参数为等待的进程集合的状态
第三个参数,默认为0,将挂起调用进程,直到等待进程集合中一个进程的终止。
wait函数
是waitpid函数的简化版
pid_t wait(int *status)
调用wait(&status)等价于调用wait(-1,&status,0)
即:等待所有的子进程(第一个参数为-1),会挂起调用的子进程直到有一个子进程终止(第三个参数options=0)
8.4.4 让进程休眠
sleep函数:
这个函数将一个进程挂起一段时间。
unsigned int sleep(unsigned int ses)
在这里输入参数为挂起的时间秒数
返回:第一种:请求的时间到了返回0,第二种:被信号中断而过早返回,返回剩下的休眠的秒数
pause函数;
该函数让调用函数休眠,直到收到一个信号
int pause(void)
总是返回-1。
8.4.5 加载并运行程序
execve函数
fork函数与execve函数的不同
(1)fork函数:
fork函数在新的子进程中运行相同的程序,新的子进程是父进程的一个复制品
(2)execve函数
在当前的进程的上下文中加载并运行一个新的程序,他会覆盖当前进程的地址空间,但并没有创建一个新的进程
新的程序仍然具有相同的进程ID,并且继承了调用execve时所有的文件描述符。