linux下的讀寫鎖詳解

2021-10-03 15:15:46 字數 2703 閱讀 7986

讀寫鎖:

讀寫鎖在寫的時候,其他人不能讀也不能寫,讀的時候,可以同時讀,但是不能寫,是一種

寫互斥,讀共享模式;讀寫鎖通常用於讀者多,寫者少的情況,這時候想要加寫鎖修改資料,但是一直都有執行緒加讀鎖,導致寫飢餓的問題,這是不合適的;因此讀寫鎖是有優先順序的,分為寫優先(加寫鎖如果加不上,在等待期間,拒絕後續的加讀鎖操作;通俗點說就是在我寫時,你不能讀,除非沒有寫者了,不然你一直在那等,直到全部執行緒都不寫了,你再加讀鎖,去寫,另外如果是寫優先,在加了讀鎖時,有寫者訪問(也就是申請讀鎖),那麼,等加了讀鎖的全部執行緒,解鎖後,後續的讀者不能申請到讀鎖,這時加寫鎖)和讀優先(加讀鎖如果加不上,在等待期間,拒絕後續的加寫鎖操作,通俗點說就是在我讀時,你不能寫,除非沒有讀者了,不然你一直在那等,直到全部執行緒都不讀了,你再加寫鎖,去寫,另外如果是讀優先,在加了寫鎖時,有讀者訪問(也就是申請讀鎖),那麼,當這個寫鎖解鎖時,後續要申請寫鎖的執行緒全部等待,讓讀者先讀);讀寫鎖預設是讀優先,因此當需要寫者優先時(讀者多,寫者少)的時候,就需要設定寫鎖屬性;設定為寫優先時,不可遞迴加鎖的意思是,加了寫鎖後,同乙個執行緒是可重入的,這時可能又會加寫鎖,是為了防止同乙個執行緒加多個寫鎖

想使用讀寫鎖就得先建立讀寫鎖變數,linux中用來建立讀寫鎖的型別是pthread_rwlock_t,不過建立成功之後還不能使用,因為看它的型別就知道是個結構體,所以它裡面還有很多狀態是未定義的,所以得先進行初始化

linux中有乙個用來初始化讀寫鎖屬性的函式是pthread_rwlockattr_init,這個函式只有乙個引數,是pthread_rwlockattr_t的指標型別,表示把你要初始化的讀寫鎖屬性變數傳入(所以你事先得通過pthread_rwlockattr_t先建立乙個讀寫鎖屬性變數),然後通過這個函式進行初始化,用這個函式初始化的屬性是預設屬性;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1

linux中還有乙個用來銷毀屬性的函式pthread_rwlockattr_destory,這個函式只有乙個引數,是pthread_rwlockattr_t的指標型別,表示把你要銷毀的讀寫鎖屬性變數傳入),然後通過;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1

因為讀寫鎖預設的優先順序是讀優先,所以當你要設定寫優先時就得呼叫linux提供的pthread_rwlockattr_setkind_np,這個函式有兩個引數,第乙個引數是pthread_rwlockattr_t的指標型別,表示把你要設定讀寫鎖優先順序屬性變數傳入,第二個引數是int型別,表示你要設定的優先順序,它有三個巨集可以使用,第乙個巨集是pthread_rwlock_prefer_reader_np表示設定為讀者優先,第二個巨集是pthread_rwlock_prefer_writer_np表示設定為寫者優先,目前有bug還是讀者優先,第三個巨集是pthread_rwlock_prefer_writer_nonrecursive_np表示設定為寫者優先,但不能遞規加鎖(不可遞迴加鎖的意思是,加了寫鎖後,同乙個執行緒是可重入的,這時可能又會加寫鎖,是為了防止同乙個執行緒加多個寫鎖)

linux中提供的讀寫鎖初始化函式是pthread_rwlockattr_init,這個函式一共有兩個引數,第乙個引數是pthread_rwlock_t的指標型別,表示你要進行初始化的讀寫鎖變數是哪個,將它的位址傳入就可以了,第二個引數是const pthread_rwlockattr_t的指標型別,表示設定讀寫鎖的屬性,通過設定為空,表示使用預設屬性;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1

當所有初始化工作完成後,我們就可以使用讀寫鎖了,當我們要加讀鎖時可以呼叫這個函式pthread_rwlock_rdlock,這個函式只有乙個引數是pthread_rwlock_t的指標型別,表示你要加讀鎖的讀寫鎖變數是哪個,將它的位址傳入就可以了;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1;這個函式是以阻塞的方式加讀鎖,意思是如果在申請讀鎖時,有寫者正在執行,以先阻塞,等寫完成任務後再獲取讀鎖

還有乙個加鎖的方式,就是以非阻塞的方式加讀鎖,意思是如果在申請讀鎖時,有寫者正在執行,獲取不了讀鎖,那麼就直接報錯返回,這個函式是pthread_rwlock_tryrdlock,它的引數和使用方法都和pthread_rwlock_rdlock函式相同

如果我們想要加寫鎖,linux提供的函式是pthread_rwlock_wrlock,這個函式只有乙個引數是pthread_rwlock_t的指標型別,表示你要加寫鎖的讀寫鎖變數是哪個,將它的位址傳入就可以了;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1;這個函式是以阻塞的方式加寫鎖,意思是如果在申請寫鎖時,有寫者正在執行,以先阻塞,等寫完成任務後再獲取寫鎖

還有乙個加鎖的方式,就是以非阻塞的方式加寫鎖,意思是如果在申請寫鎖時,有寫者正在執行,獲取不了寫鎖,那麼就直接報錯返回,這個函式是pthread_rwlock_trywrlock,它的引數和使用方法都和pthread_rwlock_wrlock函式相同

最後在使用完讀寫後,要銷毀讀寫鎖,linux提供的函式是pthread_rwlock_destory,這個函式只有乙個引數是pthread_rwlock_t的指標型別,表示你要銷毀的讀寫鎖變數是哪個,將它的位址傳入就可以了;這個函式的返回值是乙個int型別,如果初始化成功返回0,失敗則返回-1

死鎖:死鎖的產生有四個必要條件,1、互斥條件,我操作的時候別人不能操作 2、不可剝奪條件,我的鎖,別人不能解 3、請求與保持條件,就是我佔著這個資源不放,那個資源也想要,但這個資源沒處,那資源我一直在申請,所以一直鎖著我手裡的資源,一直在申請別的資源) 4、環路等待條件(就是形成乙個環路你靠我,我靠它,它靠你);死鎖的預防就是破壞必要條件,死鎖的避免可以使用銀行家演算法,死鎖檢測演算法

Linux 下的執行緒讀寫鎖

linux 下的執行緒讀寫鎖 有一種寫優先讀寫鎖,有如下特點 1 多個讀者可以同時進行讀 2 寫者必須互斥 只允許乙個寫者寫,也不能讀者寫者同時進行 3 寫者優先於讀者 一旦有寫者,則後續讀者必須等待,喚醒時優先考慮寫者 在solaris 中直接提供了讀寫鎖,但是在linux 中只提供了執行緒的讀寫...

Linux讀寫鎖的使用

目錄 1.讀寫鎖介紹 2.讀寫鎖的操作函式 3.讀寫鎖示例 讀寫鎖的型別可以分為讀鎖和寫鎖,以讀方式給資料加鎖 讀鎖。以寫方式給資料加鎖 寫鎖。但是讀寫鎖是一把鎖,每個執行緒只可以帶乙個鎖型別。特性 舉例說明 1.執行緒a加讀鎖成功,又來了三個執行緒,做讀操作,三個執行緒再次加鎖成功。結論 讀時共享...

LINUX下的執行緒同步 mutex和讀寫鎖

用mutex保護的 段,無論讀寫,乙個執行緒占有時,別的執行緒都必須等待。讀寫鎖可以使多個執行緒同時讀取,具體說來如下 當讀寫鎖是寫加鎖狀態時,在這個鎖被解鎖之前,所有試圖對這個鎖加鎖的執行緒都會被阻塞。當讀寫鎖在讀加鎖狀態時,所有試圖以讀模式對它進行加鎖的執行緒都可以得到訪問權,但是如果執行緒希望...