首页 > 代码库 > 进程与线程
进程与线程
进程
通常的程序是静态实体。在多道程序系统中。它们是不能独立运行的。更不能和其它程序并发运行。在操作系统中引入进程的目的,就是为了使多个程序可以并发运行。进程就
是指在系统中可以独立执行并作为资源分配的基本单位,它是由一组机器指令、数据和堆栈等组成的。是一个能独立执行的活动实体。
进程实体由程序段、相关的数据段和PCB(进程控制块)组成。这里我们要理解进程和普通的程序的差别。进程的实质是进程实体的一次运行过程,因此。动态性是进程的最基
本的特征,进程实体是具有生命期的,而程序则不一样,程序仅仅是一组有序指令的集合,并存放在某种介质上。其本身是静态的。
我们刚才也说过。进程的引入就是为了使得程序能够并发运行,如今我们来看看进程的同步。
很多资源比方打印机。都属于临界资源,进程之间应该採用相互排斥方式来实现对这样的资源的共享。
于是产生了一种进程同步管理方法,就是信号量机制。
信号量机制
信号量机制的原理就是为临界资源设置一个相互排斥信号量mutex,并设其初始值为1,每次訪问该资源时。对信号量进行改动,訪问完毕后将其还原就可以。
这样的方式确实是简单有
效,可是信号量大量的同步操作分散在各个进程中不便于管理,每一个进程都须要在訪问和訪问完毕后对mutex进行改动,显得过于繁琐。于是又推出了一种新的进程同步管理机
制。就是管程。
管程
管程的定义例如以下:一个管程定义了一个数据结构和能为并发进程所运行的一组操作,这组操作能同步进程和改变管程中的数据。
大约10%的人能够通过上面那句话理解管程,假设你不是那10%。请看以下我对管程通俗的理解:
管程就是一个秘书,全部进程对某一种临界资源的同步操作都集中起来给这个秘书,再由秘书来实现对同一临界资源的相互排斥使用。
由此可见,管程相当于围墙和通道。管程每次仅仅执行一个进程进入管程,从而实现了进程的相互排斥。
线程
在操作系统刚刚開始的阶段。
是没有线程这个概率的。
因为后期用户对于并发量和性能的追求,才出现了线程这个概率,线程将进程进一步的细化了。线程是进程中的实体,一
个进程能够拥有多个线程,一个线程必须有一个父进程。
线程不拥有系统资源,仅仅是执行必须的一些数据结构,它与父进程的其它线程共享该进程的全部资源。
线程是20世纪80年代中期被提出的,假设说进程是为了让多个程序能够并发运行。以提高资源利用率和系统吞吐量,那线程的目的就是降低程序在并发运行时所付出的时空开
销,使操作系统具有更好的并发性。
在多线程的操作系统中,进程不再是一个可执行的实体了,由于线程才是能够独立执行的基本单位。相同的。我们来谈谈线程的同步问题。
多线程操作系统中提供了多种线程同步机制,比方相互排斥锁,条件变量等。
相互排斥锁
相互排斥锁是一种比較简单的、用于实现线程间对资源相互排斥訪问的机制。因为操作相互排斥锁的时间和空间开销都比較低。所以比較适合高频度使用的关键共享数据和程序段。相互排斥锁有
两个状态:开锁(unlock)和关锁(lock)状态。
当一个线程须要读写一个共享数据段时,线程首先对该资源的相互排斥锁状态进行查询,假设已经处于关锁状态,则该线程将会被堵塞;假设处于开锁状态。则将锁关闭。然后继续
訪问共享资源。资源訪问完成后,必须再次开锁。并将堵塞在相互排斥锁上的进程唤醒。
这种过程看起来没有什么问题,然而只使用相互排斥锁还是有可能操作死锁。
死锁
我们通过一个样例来说明为什么相互排斥锁有可能造成死锁。
A线程对锁1关锁成功后,进入了临界资源C,然后A线程还要继续訪问资源R,则会去操作R的锁2,但是锁2已经处于关闭了,所以A线程在锁2堵塞等待。但是资源R中的B线程
要离开资源必须訪问资源C。也就是锁1必须是开启的,而A线程早已将锁1关闭了。
导致两方陷入无限等待。这就是死锁。
为了解决死锁的问题,我们增加了条件变量。
条件变量
在创建一个相互排斥锁时就联系着一个条件变量,相互排斥锁用于短期锁定,而条件变量则用于线程的长期等待。直到所等待的资源变为可用。
还是上面那个样例:
A线程对锁1关锁成果后。进入了临界资源C,然后A线程还要继续訪问资源R。则会去操作R的锁2,但是锁2已经处于关闭了。这时。线程便转入等待状态。并对锁1运行开锁操
作。等待资源R被释放。
资源R释放后,锁2已经打开。A线程顺利进入资源R,关闭锁2,并将该资源设为忙碌状态,再打开锁1。
这样就避免了死锁的问题。
进程与线程