《深刻理解计算机系统》第七章

第7章 连接程序员

连接:就是将不一样部分的代码和数据收集和组合成一个单一文件的的过程,这个文件可被加载(或被拷贝)到存储器并执行。编程

连接能够执行在编译(源代码被转化为机器代码时)时,也能够执行于加载(程序被加载器加载到存储器并执行时)时,甚至执行与运行时。函数

连接是由连接器来安静地处理的,理解连接器的好处:编码

一、帮助你构造大型程序spa

二、避免一些危险的编程错误进程

三、帮助你理解语言的做用域规则是如何实现的。事件

四、理解其余的系统概念资源

五、使你可以开发共享库。作用域

大多数编译系统提供编译驱动程序,它为用户,根据需求调用语言预处理器、编译器、汇编器和连接器。开发

为了建立可执行文件,连接器必须完成两个主要任务:

一、符号解析 (将每一个符号引用和一个符号定义联系起来)

二、重定位。编译器和汇编器生成从地址零开始的代码和数据节。连接器经过把每一个符号定义与一个存储器位置联系起来,而后对其修改全部对这些符号的引用,使他们指向这个这个存储器位置,从而重定位这些节。

 

目标文件:一、可重定位目标文件二、可执行目标文件三、共享目标文件

 

编译器和汇编器生成可重定位目标文件(包括共享目标文件)。连接器生成可执行目标文件。

一个目标模块就是一个字节序列,而一个目标文件就是一个存放在磁盘文件中的目标模块。

连接器解析符号引用的方法是将每一个引用与它输入的可重定位目标文件的符号表中的一个肯定的符号定义联系起来。

在编译时,编译器输出每一个全局符号给汇编器,或强或弱,而汇编器把这个信息隐含地编码在可重定位目标文件的符号表里。函数和已初始化的全局变量是强符号,未初始化的全局变量时弱符号。

Unix连接器处理多出定义的符号的规则:

一、不容许有多个强符号

二、若是有一个强符号和许多弱符号,那么选择强符号

三、若是所有是若符号那么任意选择。

磁盘取数据要用一段相对较长的时间,因此内核执行从进程A到进程B的上下文切换,而不是在这个时间内等待什么都不作。

每一个进程都有一个惟一的正数(非零)进程ID

对于程序员来说,咱们能够认为进程老是处于下面三种状态之一:一、运行  二、暂停   三、终止

新建的子进程几乎但不彻底与父进程相同。父进程与新建立的子进程之间最大的区别在于它们有不一样的PID.

fork函数是有趣的,由于 它只被调用一次,却会返回两次。一次在调用进程(父进程)中,一次是在新建立的子进程中。在父进程中,fork返回子进程的PID.在子进程中fork返回零,由于子进程的PID老是非零的,返回值就提供一个明确的方法来分辨程序是在父进程换是在子进程中执行的。fork函数在新的子进程中运行系相同的程序,新的子进程是父进程的一个复制品。

回收子进程:当一个进程因为某种缘由终止时,内核并非当即把它从系统中清除,取而代之的是进程被保持在一种终止状态中,直到他被父进程收回(reaped),当父进程已经收回已终止的子进程时,内核将子进程的推出状态传递给父进程,而后抛弃已终止的进程,今后时开始,该进程就不存在了。

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

若是父进程没有回收它的僵死子进程就终止了,那么内核就会安排init进程来回收他们。init进程的PID为1.而且是在系统初始化时由内核建立的。即便僵死子进程没有运行,它们仍然消耗系统的存储器资源。

等待集合的成员是由参数PID来肯定的:

一、若是pid>0,那么等待集合就是一个单独的子进程,它的进程ID等于PID

二、若是PID=-1,那么等待集合就是由父进程的全部子进程组成的。

让进程休眠:sleep函数将一个进程挂起一段时间。

加载并运行程序:execve函数在当前进程的上下文中加载并运行一个新程序。

进程和程序的区别:

程序是代码和数据的集合;程序能够做为目标模块存在于磁盘上,或者做为段存在于地址空间中。而进程是执行程序的一个特殊实例,程序老是运行在某个程序的上下文中。

信号:研究一个更高层软件形式的异常,它容许进程中断其余进程。

一个信号就是一条消息,它通知进程一个某种类型的事件已经在系统中发生。

每种信号类型都对于某个类型的系统事件。

传送一个信号到目的进程是由两个不一样步骤组成:一、发送信号二、接收信号。

一个只发出而没有被接受的信号叫作待处理信号。一个待处理信号最多被接收一次。

Unix系统提供了大量的机制,用来发送信号给进程,全部这些机制都是基于进程组。

进程组:每一个进程都只属于一个进程组,进程组是由一个正整数进程组ID来标识的。

一个子进程和它的父进程同属于一个进程组。一个进程也能够经过使用setpgid函数来改变本身活着其余进程的进程组。

接收信号:当内核从一个异常处理程序返回,准备将控制传递给进程P时,它会检查未被阻塞的待处理信号的集合,若是这个集合为空(一般状况),那么内核传递控制给P的逻辑控制流中的下一条指令。

每个信号类型都有一个预约义的默认行为:

一、进程终止。

二、进程终止并转储存储器。

三、进程暂停直到被SIGCONT信号重启。

四、进程忽略该信号。

信号处理问题:对于只捕捉一个信号并终止的程序来讲信号处理是简单直接的,然而,当一个程序要捕捉多个信号时,一些细微的问题就产生了:

一、待处理信号被阻塞。

二、带处理信号不会排队等待。任意类型至多只有一个待处理信号。有第二个信号就会被简单地丢弃。

三、系统调用能够被中断

非本地跳转:C提供一种形式的用户异常控制流,称为非本地跳转,它将控制直接从一个函数转移到另外一个当前正在执行的函数。,但不须要通过正常的调用-返回序列。

非本地跳转的一个重要应用就是循序从一个深层嵌套的函数调用中当即返回,一般是由检测到某个错误状况而引发的。若是哦在一个深层嵌套的函数调用中发现一个错误状况,咱们可使用非本地跳转直接返回到一个普通的本地化的错误处理程序,而不是费力地解开调用栈。

非本地跳转的另外一个重要应用是使一个信号处理程序分支到,一个特殊的代码位置,而不是返回到被信号到达中断了的指令的位置。

异常控制流发生在计算机系统的各个层次。

由四种不一样类型的异常:中断、故障、终止和陷阱。

相关文章
相关标签/搜索