进程

通常的程序是静态实体。在多道程序系统中。它们是不能独立运行的。更不能和其它程序并发运行。在操作系统中引入进程的目的,就是为了使多个程序可以并发运行。进程

是指在系统中可以独立执行并作为资源分配的基本单位,它是由一组机器指令、数据和堆栈等组成的。是一个能独立执行的活动实体。

进程实体由程序段、相关的数据段和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。

这样就避免了死锁的问题。