作业
用户在一次解题或一个事务处理过程中要求计算机系统所做工作的集合。它包括用户程序、所需要的数据及控制命令等。作业是由一系列有序的步骤组成的。
进程
一个程序在一个数据集合上的一次运行过程。所以一个程序在不同数据集合上运行,乃至一个程序在同样数据集合的多次运行都是不同的进程。
线程
线程是进程中的一个实体,是被系统独立调度和执行的基本单位。
进程和线程的区别
进程是程序的一次执行。线程可以理解为进程中执行的一段程序片段。
进程是独立的,这表现在内存空间、上下文环境上;线程运行在进程空间内。一般来讲(不适用特殊技术),进程无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。
同一进程中的两段代码不能同时执行,除非引入线程。
线程是属于进程的,当进程退出是该进程所产生的线程都会被强制退出并清除。线程占用的资源要少于进程所占用的资源。进程和线程都可以有优先级。
进程间可以通过IPC通信,但线程不可以。
管程
实际上定义了一个数据结构和在改数据结构上的能为并发进程所执行的一组操作,这组操作能同步进程和改变管程中的数据。
进行间的通信
现在最常用的进程间通信的方式有信号、信号量、消息队列、共享内存。
所谓进程通信,就是不同进程之间进行一些“接触”。这种接触有简单,也有复杂。机制不同,复杂度也不一样。通信是一个广义上的意义,不仅仅指传递一些message。它们的使用方法基本是相同的,所以只要掌握了一种使用方法,然后记住其他的使用方法就可以了。
信号和信号量是不同的,它们虽然都可用来实现同步和护士,但前者是使用信号处理器来进行的,后者是采用P、V操作来实现的。消息队列是比较高级的一种进程间通信方法,因为它真的可以在进程间传送message,连传送一个“I seek you”都可以。
一个消息队列可以被多个进程所共享(IPC就是在这个基础上进行的),如果一个进程消息太多,一个消息队列放不下,也可以用多于一个的消息队列(不过可能管理会比较复杂)。共享消息队列的进程所发送的消息中除了message本身外还有一个标志,这个标志可以指明该消息将由哪个进程护着是哪类进程接受。每一个共享消息队列的进程针对这个队列也有自己的标志,可以用来声明自己的身份。
死锁
死锁是指两个或两个以上的进程在执行过程中。因争夺资源而造成的互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。
产生死锁的四个必要条件如下:
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这4个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。死锁的解除与预防方法:
在系统设计、进程调度等方面注意如何不让这4个必要条件成立,如何确定资源的合理分配方法,避免进程永久占据系统资源。此外,也要防止进程处于等待状态的情况下占用资源,在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是都分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配。因此,对资源的分配要给予合理的规划。
根据产生死锁的4个必要条件,只要使其中之一不能成立,死锁就不会出现。为此,可以采取下列3中预防措施:采用资源静态分配策略,破坏“部分分配”条件 。
- 允许进程剥夺使用其他进程占有的资源,从而破坏“不可剥夺”条件。
- 采用资源有序分配阀,破坏“环路”条件。
这里注意一点,互斥条件不能被破坏。
避免死锁的经典算法:银行家算法。
内存管理
Windows内存管理方式主要分为:页式管理、段式管理、段页式管理。
页式管理的基本原理是将进程的虚拟空间划分成若干个长度相等的页;页式管理把内存空间按也得大小划分成片或者页面,然后把页式虚拟地址与内存地址简历一一对应的页表;并用相应的硬件地址变换机构来解决离散地址变换问题。页式管理采用请求调页或预调页技术来实现内外存存储器的统一管理。
优点:没有外碎片,每个内碎片不超过也页的大小。
缺点:程序全部装入内存,要求有相应的硬件支持。例如地址变换机构缺页终端的产生和选择淘汰页面等都要求有相应的硬件支持。这增加了机器成本,增加了系统的开销。
段式管理的基本思想就是把程序按内容或过程函数关系分成算,每段有自己的名字。一个用户作业或进程所包含的段对应一个二维线性虚拟空间,也就是一个二维虚拟存储器。段式管理程序以段为单位分配内存,然后通过地址映射机构把算是虚拟地址转换为实际内存物理地址。
优点:可以分别编写和编译,可以针对不同类型的段采取不同的保护,可以按段为单位来进行内存共享,包括动态链接进行代码共享。
缺点:会产生碎片。
段页式管理:为了实现段页式管理,系统必须为每个作业或进程简历一张段表以管理内存分配与释放、缺段处理等。另外由于一个段又被划分成了若干页。每个段又必须建立一张页表以把段中的虚页变换成内存中的实际页面。显然与也是管理时相同,页表中也要有相应的实现缺页中断处理和页面保护等功能的表项。
段页式管理是段式管理和页式管理方案相结合,所以具有两者的优点。
但反过来说,由于管理软件的增加,复杂性和开销也就随之增加了,另外需要的硬件以及占用的内存也有所增加,使得执行速度下降。
动态链接库/静态链接库
目前以lib为后缀的库有两种,一种为静态链接库,另一种为动态链接库(DLL)的导入库。虽然静态链接库和动态链接库的导入库都是.lib文件,但是区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、地址符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
静态链接库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确地找到是哪个obj有错,即静态lib只是壳子。当我们的应用工程在使用静态链接库的时候,静态链接库要参与编译,在生成执行文件之前的链接过程中,将静态链接库的全部指令直接连接入可执行文件中,故而,在可执行文件生成以后,静态链接库.lib文件即可以弃之不用。
动态链接库(DLL)是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个.dll文件中,该dll包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL还有助于共享数据和资源。多个应用程序可同时访问内存中单个dll副本内容。使用动态链接代替静态链接有若干优点。dll节省内存,减少交换操作,节省磁盘空间,更易于升级(不需要重链接和长编译),提供售后支持,提供扩展MFC库类的机制,支持多语言程序。
静态链接库和动态链接库都是共享代码的方式,如果采用静态链接库,lib中的指令全部被直接包含在最终生成的exe文件中了。但是若使用dll(即动态链接库),该dll不必被包含在最终的exe文件中,exe文件执行时可以“动态”地引用和卸载这个与exe独立的dll文件,静态链接库和动态链接库中还可以再包含其他的动态链接库或者静态库,而在动态链接库中还可再包含其他的动态或静态链接库。动态链接库和静态链接库的使用不同之处在于它允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位dll函数的可执行代码所需的信息。在静态链接库的使用中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。