互斥鎖和讀寫鎖的區別

原文地址:http://blog.csdn.NET/u012884354/article/details/46691761

相交進程之間的關系主要有兩種,同步與互斥。

所謂互斥,是指散布在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其它進程就不能運行它們之中的任一程序片段,只能等到該進程運行完這個程序片段后才可以運行。

所謂同步,是指散布在不同進程之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先后次序來運行,這種先后次序依賴于要完成的特定的任務。
  顯然,同步是一種更為復雜的互斥,而互斥是一種特殊的同步。
  也就是說互斥是兩個線程之間不可以同時運行,他們會相互排斥,必須等待一個線程運行完畢,另一個才能運行,而同步也是不能同時運行,但他是必須要安照某種次序來運行相應的線程(也是一種互斥)!
  總結:互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
  同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。

[html]?view plaincopy
  1. 讀寫鎖特點:??
  2. 1)多個讀者可以同時進行讀??
  3. 2)寫者必須互斥(只允許一個寫者寫,也不能讀者寫者同時進行)??
  4. 3)寫者優先于讀者(一旦有寫者,則后續讀者必須等待,喚醒時優先考慮寫者)??
  5. ???
  6. 互斥鎖特點:??
  7. ??一次只能一個線程擁有互斥鎖,其他線程只有等待??
  8. ??
  9. 互斥鎖??
  10. pthread_mutex_init()??
  11. pthread_mutex_lock()??
  12. pthread_mutex_unlock()??

  13. 讀寫鎖 ?
  14. pthread_rwlock_init()??
  15. pthread_rwlock_rdlock()??
  16. pthread_rwlock_wrlock()??
  17. pthread_rwlock_unlock()??

  18. 條件變量 ?
  19. pthread_cond_init()??
  20. pthread_cond_wait()??
  21. pthread_cond_signal()??


條件變量(Condtion Variable)是在多線程程序中用來實現“等待->喚醒”邏輯常用的方法。

舉個簡單的例子,應用程序A中包含兩個線程t1和t2。t1需要在bool變量test_cond為true時才能繼續執行,而test_cond的值是由t2來改變的,這種情況下,如何來寫程序呢?可供選擇的方案有兩種:

  • 第一種是t1定時的去輪詢變量test_cond,如果test_cond為false,則繼續休眠;如果test_cond為true,則開始執行。
  • 第二種就是上面提到的條件變量,t1在test_cond為false時調用cond_wait進行等待,t2在改變test_cond的值后,調用cond_signal,喚醒在等待中的t1,告訴t1 test_cond的值變了,這樣t1便可繼續往下執行。

    ??????很明顯,上面兩種方案中,第二種方案是比較優的。在第一種方案中,在每次輪詢時,如果t1休眠的時間比較短,會導致cpu浪費很厲害;如果t1休眠的時間比較長,又會導致應用邏輯處理不夠及時,致使應用程序性能下降。第二種方案就是為了解決輪詢的弊端而生的。然而條件變量在使用的過程中,比較容易出錯,如何用得不正確的話,會適得其反的,接下來,我將詳細分析如何來使用條件變量,希望能夠給在使用條件變量過程中遇到問題的朋友有所幫助。
    ??????在開始介紹之前,需要說明一下,在接下來的介紹中,需要用到互斥鎖和條件變量相關的內容,在這里我以Linux下的pthread_mutex_t為互斥鎖類型,pthread_cond_t為條件變量類型來進行介紹,對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

    ??????通過上面的例子,下面我來介紹一下條件變量在使用過程中需要注意的幾點(也是比較容易出錯的):
    ??????(1)條件變量的使用過程中,最為關鍵的一點是互斥鎖的使用。細心的朋友應該發現了,我在上面的例子中標了1、2、3、4、5、6個標號。在這里1、4、5、6都是正常的lock/unlock,2、3是需要特別說明的。2是進入pthread_cond_wait后的,pthread_cond_wait調的pthread_mutex_unlock,這樣做的目的是為了保證在thread1阻塞wait后,thread2獲取同一把鎖mutex的時候,能夠正常獲取(即5,6)。3是thread1被喚醒后,要退出pthead_cond_wait之前,pthread_cond_wait調的pthread_mutex_lock,這樣做的目的是為了把mutex的控制權還給調用pthread_cond_wait的線程(即thread1)。整理一下基本的時序為:

    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)條件變量使用的過程中,通常會加一個bool或者int的值test_cond來配合使用。這里需要注意的一點是一定要在signal之前來改變test_cond,這樣才能保證wait的線程被喚醒后,能夠取到正確的test_cond的值,否則后果是不可預測的。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458539.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458539.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458539.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JSP EL表達式使用

為什么80%的碼農都做不了架構師&#xff1f;>>> ##1.EL全名為Expression Language out.print(str) <%str%> ${str}例子&#xff1a; Hi! <%username%> 和 Hi! ${username}是一樣的 只要是支持servlet2.4/jsp2.0的Container就都可以在jsp網頁中直接使用e…

eclipse 中 Android sdk 無法更新的問題

誒&#xff0c;真是麻煩&#xff0c;想下個東西都下不了。我也好久沒折騰過這個了&#xff0c;在家的電腦是早就下載好了的&#xff0c;然后如今又須要下載一份。下不到。網上搜到了資料&#xff0c;記錄下來&#xff1a; 第一種方法:sdk manager - tools - option 選擇強制 xx…

iOS10 xcode8 分頁請求MJRefresh崩潰問題

MJRefresh出現崩潰現象 解決辦法&#xff1a;類庫增加判斷 if (range.location ! NSNotFound) { language [language substringToIndex:range.location]; }

網絡編程學習筆記一:Socket編程

from: http://blog.csdn.net/gneveek/article/details/8699198 “一切皆Socket&#xff01;” 話雖些許夸張&#xff0c;但是事實也是&#xff0c;現在的網絡編程幾乎都是用的socket。 ——有感于實際編程和開源項目研究。 我們深諳信息交流的價值&#xff0c;那網絡中進程之間…

JavaScript原生對象常用方法總結

這是4年前學習JavaScript基礎的學習筆記&#xff0c;當初是照著W3School教程學習的&#xff0c;4年恍然如云煙&#xff0c;仿佛還在昨天。現發布與此&#xff0c;留作紀念&#xff0c;紀念那段不悔的青蔥歲月。下面都是我學習W3C School教程中有關JavaScript寫的學習筆記&#…

[delphi]修改indy源碼后重新編譯

http://blog.csdn.net/nerdy/article/details/8702568 雖然indy有一身的毛病&#xff0c;但是一般情況下使用起來還是多方便的。 今天在做一個使用到indy的程序的時候&#xff0c;發現無論你怎么修改idhttp.request.accept-encoding&#xff0c;他都會在其后添加一個值 identit…

xcode8 崩潰問題

【1】、Xcode8代碼出現ubsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: 0, persist_level: 0, default_ttl: 0, info_ttl: 0, debug_ttl: 0, generate_symptoms: 0, enable_oversize: 1, privacy_setting: 2, enable_private_data: 0 2016-09-14 17:18:…

前端工具--less篇

前端工具–less篇 less 中文網http://www.bootcss.com/p/lesscss/ 常見錯誤及解決&#xff1a; sublime text 3 安裝less2css保存less出現錯誤 未安裝這個 npm install -g less-plugin-clean-css 未安裝這個 npm install less -gd less語法 LESS 做為 CSS 的一種形式的擴展&a…

從static變量導出問題解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

這段時間要把tinyxml從靜態庫弄成動態庫&#xff0c;要用到__declspec(dllexport)和__declspec(dllimport)來導出dll和lib文件。終于弄明白了export和import的作用&#xff0c;下面從使用的角度來說明一下他們的功能。 首先要知道&#xff0c;頭文件是C的接口文件&#xff0c;不…

4月26日作業

2016年4月26日作業 一、項目整體績效評估1、*三E審計是什么的合稱&#xff1f;&#xff08;記&#xff09; 答&#xff1a;經濟審計&#xff0c;效率審計和效果審計2、霍爾三維結構是從哪三個方面考察系統工程的工作過程的&#xff1f; 答&#xff1a;邏輯&#xff0c;時間和知…

xcode8 快捷鍵失效

因為蘋果解決xcode ghost,把插件屏蔽了。 解決方法: 命令運行&#xff1a; sudo /usr/libexec/xpccachectl 然后必須重啟電腦后生效

CAS單點登錄配置[3]:服務器端配置

在準備工作&#xff0c;證書生成等工作完成后&#xff0c;本篇介紹服務器端的配置。 JDK配置 1我們將生成的cacerts文件分別拷貝到JDK目錄下的jre/lib/security目錄下及JRE對應的目錄中&#xff0c;如果之前存在此文件&#xff0c;請替換&#xff1b; ENDTomcat配置 1Step 1:將…

DLL動態鏈接庫的工作原理

"動態鏈接"這幾字指明了DLLs是如何工作的。 對于常規的函數庫&#xff0c;鏈接器從中拷貝它需要的所有庫函數&#xff0c;并把確切的函數地址傳送給調用這些函數的程序。 而對于DLLs&#xff0c;函數儲存在一個獨立的動態鏈接庫文件中。在創建Windows程序時&#xff…

remind程序

2019獨角獸企業重金招聘Python工程師標準>>> 用了兩個定時器。一個控制刷新時間&#xff0c;一個控制響鈴。 定時器響應函數Timer: int wk; if(nIDEvent1) { CTime tCTime::GetCurrentTime(); wkt.GetDayOfWeek()-1; m_mnt.Format("%Y 年 …

查看手機是否安裝微信客戶端

if (![[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:"weixin://"]] ) {[wcatBtn setHidden:YES];}

Caffe學習系列(7):solver及其配置

solver算是caffe的核心的核心&#xff0c;它協調著整個模型的運作。caffe程序運行必帶的一個參數就是solver配置文件。運行代碼一般為 # caffe train --solver*_slover.prototxt 在Deep Learning中&#xff0c;往往loss function是非凸的&#xff0c;沒有解析解&#xff0c;我們…

Qt DLL總結-創建及調用QT的 DLL

目錄 Qt DLL總結【一】-鏈接庫預備知識 Qt DLL總結【二】-創建及調用QT的 DLL Qt DLL總結【三】-VS2008Qt 使用QPluginLoader訪問DLL 開發環境&#xff1a;VS2008Qt4.7.4 最近看了不少Qt的DLL例子&#xff0c;總結一下如何創建和調用QT 動態鏈接庫。 先講一下對QT動態鏈接庫的…

Unable to install pirate

真機測試的時候&#xff0c;報這個錯誤&#xff0c;主要原因就是證書的問題 xcode7以上進行的真機測試&#xff0c;可以沒有使用證書&#xff0c;xcode可以進行的傻瓜操作幫助我們完成真機測試&#xff0c;但是今天我進行真機測試的時候報這個錯誤&#xff0c;同時xcode也不進…

memmove 對同一個指針不操作

memmove 對同一個指針不操作&#xff0c;所以調用memmove之前不用比較兩個指針是否相同 void CTestDLLDlg::OnBnClickedButton6() {const int size 999999;char* data new char[size];memset(data, 1, size - 1);char* data1 new char[size];memset(data1, a, size - 1);clo…

.Net JIT

.Net JIT(轉) JIT 轉載于:https://www.cnblogs.com/HelloMyWorld/p/5501135.html