控制流:控制转移序列。linux
异常控制流:现代操做系统经过使控制流发生突变来对系统状态作出反应,这些突变称为异常控制流。数组
异常的剖析,以下图所示:bash
异常表:当处理器检测到有事件发生时,它会经过跳转表,进行一个间接过程调用(异常),到异常处理程序。服务器
异常号:系统中可能的某种类型的异常都分配了一个惟一的非负整数的异常号。异常号是到异常表中的索引。数据结构
一旦硬件触发了异常,异常处理程序则由软件完成。并发
Linux/IA32故障和终止函数
- 除法错误 - 通常保护故障 - 缺页 - 机器检查
程序计数器(PC)值的序列叫作逻辑控制流,简称逻辑流。以下图所示,处理器的一个物理控制流分红了三个逻辑流,每一个进程一个。学习
运行应用程序代码的进程初始时是在用户模式中的。进程从用户模式变为内核模式的惟一方法是经过异常。 linux提供了/proc文件系统,它容许用户模式进程访问内核数据结构的内容。
当内核表明用户执行上下文切换时,可能会发生上下文切换。若是系统调用发生阻塞,那么内核可让当前进程休眠,切换到另外一个进程,如read系统调用,或者sleep会显示地请求让调用进程休眠。通常,即便系统调用没有阻塞,内核亦能够决定上下文切换,而不是将控制返回给调用进程。ui
中断也可能引发上下文切换。如,定时器中断。操作系统
waitpid函数有点复杂,默认地(当options=0时),waitpid挂起调用进程的执行,知道它的等待集合中的一个子进程终止。
1.断定等待集合的成员 2.修改默认行为 3.检查已回收子进程的退出状态 4.错误条件 5.wait函数 6.使用waitpid的示例
若是请求的时间量已经到了,sleep返回0,不然返回还剩下的要休眠的秒数。后一种状况是可能的,若是由于sleep函数被一个信号中断而过早地返回。咱们将在8.5节中详细讨论信号
pause函数让调用函数休眠,直到该进程收到一个信号。
execve函数加载并运行可执行目标文件filename,且带参数列表argv和环境变量列表envp。只有当出现错误时,例如找不到filename,execve才会返回到调用程序。因此,与fork一次调用返回两次不一样,execve调用一次并从不返回。
参数中每一个指针都指向一个参数串。按照惯例,argv[0]是可执行目标文件的名字。环境变量的列表是由一个相似的数据结构表示的。envp变量指向一个以null结尾的指针数组,其中每一个指针指向个环境变量串,其中每一个串都是形如“NAME=VALUE”的名字一值对。
像Unix外壳和Web服务器这样的程序大量使用了fork和e×ecve函数。外壳是一个交互型的应用程序,它表明用户运行其余程序。最先的外壳是Sh程序,后面出现了一些变种,好比csh、tcsh、ksh和bash。外壳执行一系列的读/求值(readeaUte)步骤而后终止。
若是builtin_command返回0,那么外壳建立一个子进程,并在子进程中执行所请求的程序。若是用户要求在后台运行该程序,那么外壳返回到循环的顶部,等待下一个命令行不然,外壳使用Waitpid函数等待做业终止。看成业终止时,外壳就开始下一轮迭代。注意这个简单的外壳是有缺陷的,由于它并不回收它的后台子进程。修改这个缺陷就要求使用信号。
1.进程组
当内核从一个异常处理程序返回,准备将控制传递给进程P时,他会检查进程P的未被阻塞的处理信号的集合。若是这个集合为空,那么内核将控制传递到P的逻辑控制流中的下一条指令;若是集合是非空的,那么内核选择集合中的某个信号K(一般是最小的K0,而且强制P接收信号K。收到这个信号会触发进程的某种行为。一旦进程完成了这个行为,那么控制就传递回P的逻辑控制流中的下一条指令。
信号处理程序的执行中断main C函数的执行,相似于底层异常处理程序中断当前应用程序的控制流的方式,由于信号处理程序的逻辑控制流与主函数的逻辑控制流重叠,信号处理程序和主函数并发地运行。
(4)一旦设置了信号处理程序,它就会一直保持,知道signal带着handler参数为SIG_IGN或者SIG_DFL被调用。
-调用两次fork,一共产生四个子进程,打印四个输出行,规律为2的n次方
getpid返回调用进程的PID
getppid返回它的父进程的PID
-此程序指定了环境变量,而后依然执行了ls -l指令,成功后没有返回,因此最后一句话不会输出,结果依然相同。