(1)控制流:控制转移序列。
控制转移:从一条指令到下一条指令。
异常控制流:现代操作系统通过使控制流发生突变来对系统状态做出反应,这些突变称为异常控制流。
(2)异常:硬件触发异常,软件处理异常
(3)异常处理
异常表:当处理器检测到有事件发生时,它会通过跳转表,进行一个间接过程调用(异常),到异常处理程序。
异常号:系统中可能的某种类型的异常都分配了一个唯一的非负整数的异常号。异常号是到异常表中的索引。
一旦硬件触发了异常,异常处理程序则由软件完成。
(4)异常的类别——中断、陷阱、故障和终止
a)中断处理:异步是指硬件中断不是由任何一条指令造成的,而是由外部I/O设备的事件造成的。
b)陷阱和系统调用:系统调用是一些封装好的函数,内部通过指令int n实现。陷阱最重要的用途是提供系统调用。系统调用运行在内核模式中,并且可以访问内核中的栈。系统调用的参数是通过通用寄存器而不是栈来传递的,如,%eax存储系统调用号,%ebx,%ecx,%edx,%esi,%edi,%ebp最多存储六个参数,%esp不能用,因为进入内核模式后,会覆盖掉它。
c)故障
d)终止
(5)进程(操作系统层):逻辑控制流,私有地址空间,多任务,并发,并行,上下文,上下文切换,调度。进程就是一个执行中的程序实例。系统中的每个程序都是运行在某个进程的上下文中的。 进程提供给应用程序的关键抽象:a)一个独立的逻辑控制流 ;b)一个私有的地址空间
#逻辑控制流- 程序计数器(PC)值的序列叫做逻辑控制流,简称逻辑流。如下图所示,处理器的一个物理控制流分成了三个逻辑流,每个进程一个。
一些概念:并发流:并发流一个逻辑流的执行在时间上与另一个流重叠
并发:多个流并发执行的一般现象称为并发。
多任务:多个进程并发叫做多任务。
并行:并发流在不同的cpu或计算机上,
#私有地址空间-一个进程为每个程序提供它自己的私有地址空间。运行应用程序代码的进程初始时是在用户模式中的。进程从用户模式变为内核模式的唯一方法是通过异常。linux提供了/proc文件系统,它允许用户模式进程访问内核数据结构的内容。
(6)进程控制
创建和终止进程:进程的三种状态——运行、停止和终止。进程会因为三种原因终止进程:收到信号,该信号默认终止进程;从主程序返回;调用exit函数。
(7)回收子进程:
回收:当一个进程终止时,内核并不立即把它从系统中清除。相反,进程被保持在一种已终止的状态中,直到被它的父进程回收。
僵死进程:一个终止了但是还未被回收的进程称为僵死进程。
回收子进程的两种方法:1,内核的init进程 2,父进程waitpid函数
-如果父进程没有回收它的僵死子进程就终止了,那么内核就会安排init进城来回收它们。init进程的PID为1,并且是在系统初始化时创建的。
-个进程可以通过调用waitpid函数来等待它的子进程终止或停止。
waitpid函数有点复杂,默认地(当options=0时),waitpid挂起调用进程的执行,知道它的等待集合中的一个子进程终止。
(8) wait函数:
wait(&status)函数,等价于调用wait(-1,&status,0)
让进程休眠:
sleep函数将一个进程挂起一段指定的时间。
pause函数让调用函数休眠,知道该进程收到一个信号。
(9)环境数组操作函数:
(10)信号(操作系统和应用程序之间):进程之间传送信号,一种更高层次的软件形式的异常,称为unix信号,它允许进程中断其他进程。低层的硬件异常是由内核异常处理程序处理的,正常情况下,对用户进程而言是不可见的。信号提供了一种机制,通知用户进程发生了这些异常。
(11)信号处理过程
#发送信号:内核通过更新目的进程中上下文中的某个状态,发送一个信号给目的进程。发送信号有两个原因:a)内核检测到一个系统事件; b)一个进程调用kill函数,心事发送信号
#接收信号:,目的进程就接收了信号。进程可以忽略这个信号,终止或者通过执行信号处理程序捕获这个信号。
注意:待处理信号,一种类型的信号只能有一种待处理信号,多余的不会排队,而是会舍掉 ; 信号还可以阻塞。
(12)发送信号:/bin/kill , kill函数,键盘,alarm函数
进程组:每个进程都只属于一个进程组,进程组是由一个进程组ID来标识的。默认的,一个子进程和它的父进程同属于一个进程组。在任何时刻,至多只有一个前台作业和0个或多个后台作业。外壳为每个作业创建一个独立的进程组,一个作业对应一个进程组。
用kill函数发送信号:发送SIGKILL信号
用alarm函数发送信号:发送SOGALARM信号
(13)接收信号,进程可以通过使用signal函数来修改和信号相关的默认行为。唯一的例外是SIGSTOP和SIGKILL,它们的默认行为不能被修改。
(14)信号处理问题, 当一个程序捕获多个信号时,容易有一些细问问题:
可移植的信号处理:目的是为了统一同一信号在不通系统中的语义。sigaction函数,或者是它的包装函数Signal函数。
(15)同步流以避免并发的错误,如何编写读写相同存储位置的并发流程序的问题,困扰着数代计算机科学家。比如,竞争问题。程序示例如下:
容易出现以下问题:
(16)非本地跳转(应用层) c语言提供了一种用户级异常控制流形式,称为本地跳转。通过setjmp和longjmp函数来提供。
setjmp函数只被调用一次,但返回多次:一次是当第一次调用setjmp,而调用环境保存在缓冲区env中时,一次是为每个相应的longjmp调用。另一方面,longjmp只调用一次,但从不返回。sig—函数是setjmp和longjmp函数的可以被信号处理程序使用的版本。
非本地跳转的一个重要应用就是允许从一个深层嵌套的函数调用中立即返回,通常是由检测到某个错误情况引起的。
非本地跳转的另一个重要应用是使一个信号处理程序分支到一个特殊的代码位置,而不是返回到达中断了的指令位置。
遇到的问题
原文:http://www.cnblogs.com/baka/p/4985831.html