原文:http://blog.csdn.net/luoweifu/article/details/46701167
做者:luoweifu
转载请标名出处linux
如今主流操做系统(如Windows、Linux、Mac OS X)的任务调度除了具备前面提到的时间片轮转的特色外,还有优先级调度(Priority Schedule)的特色。优先级调度决定了线程按照什么顺序轮流执行,在具备优先级调度的系统中,线程拥有各自的线程优先级(Thread Priority)。具备高优先级的线程会更早地执行,而低优先级的线程一般要等没有更高优先级的可执行线程时才会被执行。安全
线程的优先级能够由用户手动设置,此外系统也会根据不一样情形调整优先级。一般状况下,频繁地进入等待状态(进入等待状态会放弃以前仍可占用的时间份额)的线程(如IO线程),比频繁进行大量计算以致于每次都把全部时间片所有用尽的线程更受操做系统的欢迎。由于频繁进入等待的线程只会占用不多的时间,这样操做系统能够处理更多的任务。咱们把频繁等待的线程称之为IO密集型线程(IO Bound Thread),而把不多等待的线程称之为CPU密集型线程(CPU Bound Thread)。IO密集型线程老是比CPU密集型线程更容易获得优先级的提高。markdown
在优先级调度下,容易出现一种线程饿死的现象。一个线程饿死是说它的优先级较低,在它执行以前老是有比它优先级更高的线程等待执行,所以这个低优先级的线程始终得不到执行。当CPU密集型的线程优先级较高时,其它低优先级的线程就极可能出现饿死的状况;当IO密集型线程优先级较高时,其它线程相对不容易形成饿死的善,由于IO线程有大量的等待时间。为了不线程饿死,调度系统一般会逐步提高那些等待了好久而得不到执行的线程的优先级。这样,一个线程只要它等待了足够长的时间,其优先级总会被提高到可让它执行的程度,也就是说这种状况下线程始终会获得执行,只是时间的问题。并发
在优先级调度环境下,线程优先级的改变有三种方式:
1. 用户指定优先级;
2. 根据进入等待状态的频繁程度提高或下降优先级(由操做系统完成);
3. 长时间得不到执行而被提高优先级。post
在多个线程并发执行访问同一个数据时,若是不采起相应的措施,将会是很是危险的。假设你在工行有一个银行帐户,两张银联卡(本身手里一张,女友手里一张),里面有100万。假设取钱就两个过程:1.检查帐户余额,2.取出现金(若是要取出的金额 > 帐户余额,则取现成功,不然取现失败)。有一天你要买房想把钱取出来,而此时你女友也想买一辆车(假设大家事先没有商量)。两我的都在取钱,你在A号ATM机取100万,女友在B号ATM机取80万。这时A号ATM检查帐户余额发现有100万,能够取出;而与此同时,同一时刻B号ATM也在检查帐户余额发现有100万,能够取出;这样,A、B都把钱取出来了。ui
100万的存款取出180万,银行就亏大发了(固然你就笑呵呵了……)!这就是线程并发的不安全性。为避免这种状况发生,咱们要将多个线程对同一数据的访问同步,确保线程安全。spa
所谓同步(synchronization)就是指一个线程访问数据时,其它线程不得对同一个数据进行访问,即同一时刻只能有一个线程访问该数据,当这一线程访问结束时其它线程才能对这它进行访问。同步最多见的方式就是使用锁(Lock),也称为线程锁。锁是一种非强制机制,每个线程在访问数据或资源以前,首先试图获取(Acquire)锁,并在访问结束以后释放(Release)锁。在锁被占用时试图获取锁,线程会进入等待状态,直到锁被释放再次变为可用。操作系统
二元信号量(Binary Semaphore)是一种最简单的锁,它有两种状态:占用和非占用。它适合只能被惟一一个线程独占访问的资源。当二元信号量处于非占用状态时,第一个试图获取该二元信号量锁的线程会得到该锁,并将二元信号量锁置为占用状态,以后其它试图获取该二元信号量的线程会进入等待状态,直到该锁被释放。.net
多元信号量容许多个线程访问同一个资源,多元信号量简称信号量(Semaphore),对于容许多个线程并发访问的资源,这是一个很好的选择。一个初始值为N的信号量容许N个线程并发访问。线程访问资源时首先获取信号量锁,进行以下操做:
1. 将信号量的值减1;
2. 若是信号量的值小于0,则进入等待状态,不然继续执行;
访问资源结束以后,线程释放信号量锁,进行以下操做:
1. 将信号量的值加1;
2. 若是信号量的值小于1(等于0),唤醒一个等待中的线程;线程
互斥量(Mutex)和二元信号量相似,资源仅容许一个线程访问。与二元信号量不一样的是,信号量在整个系统中能够被任意线程获取和释放,也就是说,同一个信号量能够由一个线程获取而由另外一线程释放。而互斥量则要求哪一个线程获取了该互斥量锁就由哪一个线程释放,其它线程越俎代庖释放互斥量是无效的。
临界区(Critical Section)是一种比互斥量更加严格的同步手段。互斥量和信号量在系统的任何进程都是可见的,也就是说一个进程建立了一个互斥量或信号量,另外一进程试图获取该锁是合法的。而临界区的做用范围仅限于本进程,其它的进程没法获取该锁。除此之处,临界区与互斥量的性质相同。
读写锁(Read-Write Lock)容许多个线程同时对同一个数据进行读操做,而只容许一个线程进行写操做。这是由于读操做不会改变数据的内容,是安全的;而写操做会改变数据的内容,是不安全的。对同一个读写锁,有两种获取方式:共享的(Shared)和独占的(Exclusive)。当锁处于自由状态时,试图以任何一种方式获取锁都能成功,并将锁置为对应的状态;若是锁处于共享状态,其它线程以共享方式获取该锁,仍然能成功,此时该锁分配给了多个线程;若是其它线程试图如独占的方式获取处于共享状态的锁,它必须等待全部线程释放该锁;处于独占状态的锁阻止任何线程获取该锁,不论它们以何种方式。获取读写锁的方式总结以下:
读写锁的状态 | 以共享方式获取 | 以独占方式获取 |
---|---|---|
自由 | 成功 | 成功 |
共享 | 成功 | 等待 |
独占 | 等待 | 等待 |
若是您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!因为本人技术和能力有限,若是本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!
原文:http://blog.csdn.net/luoweifu/article/details/46701167
做者:luoweifu 转载请标名出处