互斥锁和读写锁的区别
原文地址:http://blog.csdn.NET/u012884354/article/details/46691761
相交進(jìn)程之間的關(guān)系主要有兩種,同步與互斥。
所謂互斥,是指散布在不同進(jìn)程之間的若干程序片斷,當(dāng)某個(gè)進(jìn)程運(yùn)行其中一個(gè)程序片段時(shí),其它進(jìn)程就不能運(yùn)行它們之中的任一程序片段,只能等到該進(jìn)程運(yùn)行完這個(gè)程序片段后才可以運(yùn)行。
所謂同步,是指散布在不同進(jìn)程之間的若干程序片斷,它們的運(yùn)行必須嚴(yán)格按照規(guī)定的某種先后次序來運(yùn)行,這種先后次序依賴于要完成的特定的任務(wù)。
顯然,同步是一種更為復(fù)雜的互斥,而互斥是一種特殊的同步。
也就是說互斥是兩個(gè)線程之間不可以同時(shí)運(yùn)行,他們會(huì)相互排斥,必須等待一個(gè)線程運(yùn)行完畢,另一個(gè)才能運(yùn)行,而同步也是不能同時(shí)運(yùn)行,但他是必須要安照某種次序來運(yùn)行相應(yīng)的線程(也是一種互斥)!
總結(jié):互斥:是指某一資源同時(shí)只允許一個(gè)訪問者對(duì)其進(jìn)行訪問,具有唯一性和排它性。但互斥無法限制訪問者對(duì)資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎(chǔ)上(大多數(shù)情況),通過其它機(jī)制實(shí)現(xiàn)訪問者對(duì)資源的有序訪問。在大多數(shù)情況下,同步已經(jīng)實(shí)現(xiàn)了互斥,特別是所有寫入資源的情況必定是互斥的。少數(shù)情況是指可以允許多個(gè)訪問者同時(shí)訪問資源。
[html]?view plaincopy
條件變量(Condtion Variable)是在多線程程序中用來實(shí)現(xiàn)“等待->喚醒”邏輯常用的方法。
舉個(gè)簡單的例子,應(yīng)用程序A中包含兩個(gè)線程t1和t2。t1需要在bool變量test_cond為true時(shí)才能繼續(xù)執(zhí)行,而test_cond的值是由t2來改變的,這種情況下,如何來寫程序呢?可供選擇的方案有兩種:
- 第一種是t1定時(shí)的去輪詢變量test_cond,如果test_cond為false,則繼續(xù)休眠;如果test_cond為true,則開始執(zhí)行。
- 第二種就是上面提到的條件變量,t1在test_cond為false時(shí)調(diào)用cond_wait進(jìn)行等待,t2在改變test_cond的值后,調(diào)用cond_signal,喚醒在等待中的t1,告訴t1 test_cond的值變了,這樣t1便可繼續(xù)往下執(zhí)行。
??????很明顯,上面兩種方案中,第二種方案是比較優(yōu)的。在第一種方案中,在每次輪詢時(shí),如果t1休眠的時(shí)間比較短,會(huì)導(dǎo)致cpu浪費(fèi)很厲害;如果t1休眠的時(shí)間比較長,又會(huì)導(dǎo)致應(yīng)用邏輯處理不夠及時(shí),致使應(yīng)用程序性能下降。第二種方案就是為了解決輪詢的弊端而生的。然而條件變量在使用的過程中,比較容易出錯(cuò),如何用得不正確的話,會(huì)適得其反的,接下來,我將詳細(xì)分析如何來使用條件變量,希望能夠給在使用條件變量過程中遇到問題的朋友有所幫助。
??????在開始介紹之前,需要說明一下,在接下來的介紹中,需要用到互斥鎖和條件變量相關(guān)的內(nèi)容,在這里我以Linux下的pthread_mutex_t為互斥鎖類型,pthread_cond_t為條件變量類型來進(jìn)行介紹,對(duì)pthread不熟的朋友,可以參考一下linux下的manual。
??????1. 下面是把剛開始舉的例子翻譯后的程序:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 pthread_mutex_t mutex; ///< 互斥鎖 pthread_cond_t cond; ///< 條件變量 bool test_cond = false; /// TODO 初始化mutex和cond/// thread 1: pthread_mutex_lock(&mutex); ///< 1 while (!test_cond) {pthread_cond_wait(&cond, &mutex); ///< 2,3 } pthread_mutex_unlock(&mutex); ///< 4 RunThread1Func();/// thread 2: pthread_mutex_lock(&mutex); ///< 5 test_cond = true; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); ///< 6/// TODO 銷毀mutex和cond ??????通過上面的例子,下面我來介紹一下條件變量在使用過程中需要注意的幾點(diǎn)(也是比較容易出錯(cuò)的):
??????(1)條件變量的使用過程中,最為關(guān)鍵的一點(diǎn)是互斥鎖的使用。細(xì)心的朋友應(yīng)該發(fā)現(xiàn)了,我在上面的例子中標(biāo)了1、2、3、4、5、6個(gè)標(biāo)號(hào)。在這里1、4、5、6都是正常的lock/unlock,2、3是需要特別說明的。2是進(jìn)入pthread_cond_wait后的,pthread_cond_wait調(diào)的pthread_mutex_unlock,這樣做的目的是為了保證在thread1阻塞wait后,thread2獲取同一把鎖mutex的時(shí)候,能夠正常獲取(即5,6)。3是thread1被喚醒后,要退出pthead_cond_wait之前,pthread_cond_wait調(diào)的pthread_mutex_lock,這樣做的目的是為了把mutex的控制權(quán)還給調(diào)用pthread_cond_wait的線程(即thread1)。整理一下基本的時(shí)序?yàn)?#xff1a;1 2 3 thread 1 lock->thread 1 wait-> thread 1 unlock(in wait) ->thread 2 lock->thread 2 signal->thread 2 unlock ->thread 1 lock(in wait)->thread 1 unlock ??????(2)條件變量使用的過程中,通常會(huì)加一個(gè)bool或者int的值test_cond來配合使用。這里需要注意的一點(diǎn)是一定要在signal之前來改變test_cond,這樣才能保證wait的線程被喚醒后,能夠取到正確的test_cond的值,否則后果是不可預(yù)測的。
總結(jié)
以上是生活随笔為你收集整理的互斥锁和读写锁的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring boot security
- 下一篇: SIFT算法简介