进程
定义
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
进程间的通信
#管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
#有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
# 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
# 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
# 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
管程
信号量机制虽然是一种既方便又有效的进程同步机制,但是每个访问理解资源的进程都必须自备同步操作,不仅给系统管理带来麻烦,还很容易因同步操作不当造成系统死锁。这样一个新的进程同步工具就出现了——管程。
定义
代表系统共享资源的数据结构,以及有对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成一个操作系统的资源管理模块,我们称之为“管程”。
管程被请求资源的进程所调用,有四部分组成:①管程的名称;②局部于管程内部的数据结构的说明;③对该数据结构进行操作的一组过程;④对局部于管程内部的共享数据设置初始值的语句;
管程相当于围墙,将共享数据结构全部圈了起来,只留下入口和出口,并且拥有自己的消息队列,每当进程要访问共享资源的时候,必须经过管程才能进入,而管程每次只准许一个进程进入管程,从而实现互斥。
管程的特性:
- 模块化。管程是一个基本程序单位,可以独立编译。
- 抽象数据类型。管程中不仅有数据,还有对数据的操作。
- 信息掩蔽。管程中的数据必须只能被管程来访问,这些过程也是在管程内部定义的,供管程外的进程调用,而管程中的数据结构以及具体实现外部都是不可见的。
管程与进程的区别:
1、二者虽然都定义的数据结构,但是进程的数据结构PCB是进程私有的,管程的数据结构是公共数据结构,如消息队列;
2、二者都存在对各自数据结构的操作,但进程是由顺序程序执行有关的操作,而管程主要是进行同步操作和资源初始化操作;
3、设置进程的目的就是实现系统的并发性,而管程是解决资源的同步使用问题;
4、进程通过调用管程中的过程来对共享数据结构进行操作,该过程就如同子程序一样被调用,因而进程的工作方式是主动的,而管程是被动的。
5、进程之间可以并发,但是管程是不能与其调用者并发的
6、进程具有动态性,而管程是操作系统中的一个资源管理模块,供进程调用。
线程
进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:
进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
如果这两个缺点理解比较困难的话,举个现实的例子也许你就清楚了:如果把我们上课的过程看成一个进程的话,那么我们要做的是耳朵听老师讲课,手上还要记笔记,脑子还要思考问题,这样才能高效的完成听课的任务。而如果只提供进程这个机制的话,上面这三件事将不能同时执行,同一时间只能做一件事,听的时候就不能记笔记,也不能用脑子思考,这是其一;如果老师在黑板上写演算过程,我们开始记笔记,而老师突然有一步推不下去了,阻塞住了,他在那边思考着,而我们呢,也不能干其他事,即使你想趁此时思考一下刚才没听懂的一个问题都不行,这是其二。
现在你应该明白了进程的缺陷了,而解决的办法很简单,我们完全可以让听、写、思三个独立的过程,并行起来,这样很明显可以提高听课的效率。而实际的操作系统中,也同样引入了这种类似的机制——线程。
线程的优点
因为要并发,我们发明了进程,又进一步发明了线程。只不过进程和线程的并发层次不同:进程属于在处理器这一层上提供的抽象;线程则属于在进程这个层次上再提供了一层并发的抽象。如果我们进入计算机体系结构里,就会发现,流水线提供的也是一种并发,不过是指令级的并发。这样,流水线、线程、进程就从低到高在三个层次上提供我们所迫切需要的并发!
除了提高进程的并发度,线程还有个好处,就是可以有效地利用多处理器和多核计算机。现在的处理器有个趋势就是朝着多核方向发展,在没有线程之前,多核并不能让一个进程的执行速度提高,原因还是上面所有的两点限制。但如果讲一个进程分解为若干个线程,则可以让不同的线程运行在不同的核上,从而提高了进程的执行速度。
例如:我们经常使用微软的Word进行文字排版,实际上就打开了多个线程。这些线程一个负责显示,一个接受键盘的输入,一个进行存盘等等。这些线程一起运行,让我们感觉到我们输入和屏幕显示同时发生,而不是输入一些字符,过一段时间才能看到显示出来。在我们不经意间,还进行了自动存盘操作。这就是线程给我们带来的方便之处。
进程与线程的区别
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体, 是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
一个程序至少有一个进程,一个进程至少有一个线程. 一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行,线程共享除了堆栈以外的进程资源。 与进程的控制表PCB相似,线程也有自己的控制表TCB,但是TCB中所保存的线程状态比PCB表少得多。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
死锁
产生原因
- 资源竞争
- 进程间推进
产生死锁的必要条件
- 互斥
- 请求和保持
- 不剥夺
- 环路等待
预防死锁
在产生死锁的必要条件上,加上摒弃(除了互斥条件,因为摒弃互斥,就不能保证并发的正确性了)
- 摒弃请求和保持
系统规定所有进程在开始执行之前,都要一次性的申请所需的全部资源。
- 摒弃环路等待
所有进程对资源的请求顺序必须按照资源号递增的顺序提出。
- 摒弃不剥夺
当一个进程已经拥有资源,并且又要请求新的资源的时候不能立即得到满足,必须立即释放它原有占有的资源,如果以后还需要此类资源,可以再重新申请。
避免死锁
银行家算法来进行死锁的避免。
检测死锁
保存有关资源的请求和分配信息
提供一种算法,以利用这些信息来检测系统是否已进入死锁状态
解除死锁
剥夺资源
撤销进程