Linux使用互斥鎖和條件變數實現讀寫鎖(寫優先)
(1)只要沒有執行緒持有某個給定的讀寫鎖用於寫,那麼任意數目的執行緒可以持有該讀寫鎖用於讀
(2)僅當沒有執行緒持有某個讀寫鎖用於讀或用於寫時,才能分配該讀寫鎖用於寫
換一種說法就是,只要沒有執行緒在修改(寫)某個給定的資料,那麼任意數目的執行緒都可以擁有該資料的訪問權(讀)。僅當沒有其它執行緒在讀或者修改(寫)某個給定的資料時,當前執行緒才可以修改(寫)它。
因此,讀為共享,寫為獨佔。
本程式只實現了一種可能,即優先考慮等待著的寫入者,可有其他實現方案。
//my_pthread_rwlock.h #pragma once #include<pthread.h> #include<stdio.h> typedef struct { pthread_mutex_t rw_mutex; pthread_cond_t rw_condreaders; pthread_cond_t rw_condwriters; int rw_magic; int rw_nwaitreaders; int rw_nwaitwriters; int rw_refcount; // 0 >0 ==-1 }my_pthread_rwlock_t; #define RW_MAGIC 0x20180326 #define EBUSY 22 #define MY_PTHREAD_RWLOCK_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER,\ RW_MAGIC,0,0,0} typedef int my_pthread_rwlockattr_t; int my_pthread_rwlock_init(my_pthread_rwlock_t *rw, my_pthread_rwlockattr_t *attr); int my_pthread_rwlock_destroy(my_pthread_rwlock_t *rw); int my_pthread_rwlock_rdlock(my_pthread_rwlock_t *rw); int my_pthread_rwlock_wrlock(my_pthread_rwlock_t *rw); int my_pthread_rwlock_unlock(my_pthread_rwlock_t *rw); int my_pthread_rwlock_tryrdlock(my_pthread_rwlock_t *rw); int my_pthread_rwlock_trywrlock(my_pthread_rwlock_t *rw); //my_pthread_rwlock.c #include"my_pthread_rwlock.h" #include<pthread.h> int my_pthread_rwlock_init(my_pthread_rwlock_t *rw, my_pthread_rwlockattr_t *attr) { int result; if(attr != NULL) return -1; if((result = pthread_mutex_init(&rw->rw_mutex,NULL))!=0) goto err1; if((result = pthread_cond_init(&rw->rw_condreaders,NULL))!=0) goto err2; if((result = pthread_cond_init(&rw->rw_condwriters,NULL))!=0) goto err3; rw->rw_nwaitreaders=0; rw->rw_nwaitwriters=0; rw->rw_refcount=0; rw->rw_magic=RW_MAGIC; return 0; err3:pthread_cond_destory(&rw->rw_condreaders); err2:pthread_mutex_destory(&rw->rw_mutex); err1:return result; } int my_pthread_rwlock_rdlock(my_pthread_rwlock_t *rw) { int result; if(rw->rw_magic != RW_MAGIC) return -1; if((result = pthread_mutex_lock(&rw->rw_mutex)) != 0) return result; while(rw->rw_refcount<0 || rw->rw_nwaitwriters>0) { rw->rw_nwaitreaders++; result = pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex); rw->rw_nwaitreaders--; if(result != 0) break; } if(result == 0) rw->rw_refcount++; pthread_mutex_unlock(&rw->rw_mutex); return result; } int my_pthread_rwlock_wrlock(my_pthread_rwlock_t *rw) { int result; if(rw->rw_magic != RW_MAGIC) return -1; if((result = pthread_mutex_lock(&rw->rw_mutex)) != 0) return result; while(rw->rw_refcount != 0) { rw->rw_nwaitwriters++; result = pthread_cond_wait(&rw->rw_condwriters, &rw->rw_mutex); rw->rw_nwaitwriters--; if(result != 0) break; } if(result == 0) rw->rw_refcount = -1; pthread_mutex_unlock(&rw->rw_mutex); return result; } int my_pthread_rwlock_unlock(my_pthread_rwlock_t *rw) { int result; if(rw->rw_magic != RW_MAGIC) return -1; if((result = pthread_mutex_lock(&rw->rw_mutex)) != 0) return result; if(rw->rw_refcount > 0) rw->rw_refcount--; else if(rw->rw_refcount == -1) rw->rw_refcount = 0; else printf("unlock error.\n"); if(rw->rw_nwaitwriters > 0) { if(rw->rw_refcount == 0) { result = pthread_cond_signal(&rw->rw_condwriters); } } else if(rw->rw_nwaitreaders > 0) result = pthread_cond_broadcast(&rw->rw_condreaders); pthread_mutex_unlock(&rw->rw_mutex); return result; } int my_pthread_rwlock_tryrdlock(my_pthread_rwlock_t *rw) { int result; if(rw->rw_magic!=RW_MAGIC) return -1; if((result = pthread_mutex_lock(&rw->rw_mutex))!=0) return result; if(rw->rw_refcount!=0||rw->rw_nwaitwriters>0) result=EBUSY; else rw->rw_refcount++; return result; } int my_pthread_rwlock_trywrlock(my_pthread_rwlock_t *rw) { int result; if(rw->rw_magic!=RW_MAGIC) return -1; if((result = pthread_mutex_lock(&rw->rw_mutex))!=0) return result; if(rw->rw_refcount!=0) result=EBUSY; else rw->rw_refcount=-1; pthread_mutex_unlock(&rw->rw_mutex); return result; } int my_pthread_rwlock_destroy(my_pthread_rwlock_t *rw) { if(rw->rw_magic!=RW_MAGIC) return -1; if(rw->rw_refcount!=0||rw->rw_nwaitreaders!=0||rw->rw_nwaitwriters!=0) return EBUSY; pthraed_mutex_destory(&rw->rw_mutex); pthread_cond_destory(&rw->rw_condreaders); pthread_cond_destory(&rw->rw_condwriters); rw->rw_magic=0; return 0; } //main.c #include<stdio.h> #include<unistd.h> #include<pthread.h> #include"my_pthread_rwlock.h" my_pthread_rwlock_t rwlock = MY_PTHREAD_RWLOCK_INITIALIZER; void * thread_fun1(void *arg) { } void * thread_fun2(void *arg) { } void * thread_fun3(void *arg) { } int main() { pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, thread_fun1, NULL); sleep(1); pthread_create(&tid2, NULL, thread_fun2, NULL); pthread_create(&tid3, NULL, thread_fun3, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); return 0; }
相關推薦
Linux使用互斥鎖和條件變數實現讀寫鎖(寫優先)
(1)只要沒有執行緒持有某個給定的讀寫鎖用於寫,那麼任意數目的執行緒可以持有該讀寫鎖用於讀(2)僅當沒有執行緒持有某個讀寫鎖用於讀或用於寫時,才能分配該讀寫鎖用於寫換一種說法就是,只要沒有執行緒在修改(寫)某個給定的資料,那麼任意數目的執行緒都可以擁有該資料的訪問權(讀)。僅
通過互斥鎖和條件變數實現佇列的無sleep生產與消費
昨天轉了一篇文章將條件變數與互斥鎖的結合使用,今天給大家摳出曾經學到的一段高效的處理訊息的demo,通過互斥鎖實現安全佇列,通過條件變數實現佇列的工作與休息。 目錄結構: 簡單介紹: SignalThread是封裝好的執行緒類,我們所做的核心工作都是在這裡完成,其他類也是服務於這裡;
多執行緒用互斥鎖和條件變數實現生產者和消費者-------迴圈任務佇列
互斥鎖與條件變數簡介 在多執行緒的環境中,全域性變數會被各執行緒共享,因此在操作全域性變數的時候需要採用鎖機制,在linux裡最常用的鎖就是互斥鎖,互斥鎖使用方法如下 <pre name="code" class="cpp">//執行緒A pthread_mut
互斥量和條件變數實現生產者消費者模型
/*producer and constmer*/ #include<stdio.h> #include<pthread.h> #include<string.h>
linux下用互斥鎖和條件變數來實現讀寫鎖
以下內容來源自UNP卷二的第八章 讀寫鎖的概念( the conception of read-write lock ) (1)只要沒有執行緒持有某個給定的讀寫鎖用於寫,那麼任意數目的執行緒可以持有該執行緒用於讀 (2)僅當沒有執行緒持有某個給定的讀寫鎖用於讀或用於寫,才能分配該
訊號量、互斥鎖、讀寫鎖和條件變數之間的區別
訊號量 強調的是執行緒(或程序)間的同步:“訊號量用在多執行緒多工同步的,一個執行緒完成了某一個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作(大家都在sem_wait的時候,就阻塞在那裡)。當訊號量為單值訊號量是,也可以完成一個資源的互斥訪問。 有名
Linux多執行緒學習(2)--執行緒的同步與互斥及死鎖問題(互斥量和條件變數)
Linux多執行緒學習總結 一.互斥量 1.名詞理解 2.什麼是互斥量(mutex) 3.互斥量的介面 3.1 初始化訊號量 3.2 銷燬訊號量 3.3 互斥量加鎖和解鎖
Linux程序通訊[2]-互斥鎖和條件變數
概述 上一篇介紹了共享記憶體,已經屬於比較高階的層次。本篇介紹一下多執行緒/多程序最基礎的問題,同步。 為了允許線上程或程序間共享資料,同步常常是必需的,也就是我們常說要用鎖(當然鎖通常也是效能瓶頸,現在無鎖架構正在越發流行)。互斥鎖和條件變數則是同步的基本組成部分。互斥鎖和條件變數在同一程序下的所有
Linux C互斥鎖和條件變數(POSIX標準)
與程序類似,執行緒也存在同步的問題,當多個控制執行緒共享相同的記憶體時,需要確保每個執行緒看到一致的資料檢視,如果每個執行緒使用的變數都是其他執行緒不會讀取或修改的(比如執行緒私有資料),就不會存在一致性問題。通常來說使用者可以使用互斥量(互斥鎖)或者的條件變數
Linux多執行緒消費者和生產者模型例項(互斥鎖和條件變數使用)
條件變數簡單介紹: 條件變數是執行緒可以使用的另一種同步機制。條件變數與互斥量一起使用的時候,允許執行緒以無競爭的方式等待特定的條件發生。條件本身是由互斥量保護的。執行緒在改變條件變數狀態前必須先鎖住互斥量。另一種是動態分配的條件變數,則用pthread_cond_ini
Linux下多執行緒程式設計互斥鎖和條件變數的簡單使用
Linux下的多執行緒遵循POSIX執行緒介面,稱為pthread。編寫Linux下的多執行緒程式,需要使用標頭檔案pthread.h,連結時需要使用庫libpthread.a。執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位。執行緒
執行緒私有資料TSD——一鍵多值技術,執行緒同步中的互斥鎖和條件變數
一:執行緒私有資料: 執行緒是輕量級程序,程序在fork()之後,子程序不繼承父程序的鎖和警告,別的基本上都會繼承,而vfork()與fork()不同的地方在於vfork()之後的程序會共享父程序的地址空間,但是有了寫實複製(fork()之後的子程序也不會直接
C++ 併發程式設計之互斥鎖和條件變數的效能比較
介紹 本文以最簡單生產者消費者模型,通過執行程式,觀察該程序的cpu使用率,來對比使用互斥鎖 和 互斥鎖+條件變數的效能比較。 本例子的生產者消費者模型,1個生產者,5個消費者。 生產者執行緒往佇列裡放入資料,5個消費者執行緒從佇列取資料,取資料前需要判斷一下佇列中是否有資料,這個佇列是全域性佇列,是執行緒間
【Java併發程式設計】之二十:併發新特性—Lock鎖和條件變數(含程式碼)
簡單使用Lock鎖 Java 5中引入了新的鎖機制——java.util.concurrent.locks中的顯式的互斥鎖:Lock介面,它提供了比synchronized更加廣泛的鎖定操作。Lock介面有3個實現它的類:ReentrantLock、Reetrant
關於互斥量和條件變數
條件變數一般用於阻塞執行緒以及給執行緒發訊號,解除阻塞。而條件變數往往和互斥量一起使用,因為條件變數在阻塞的時候會有一個加鎖解鎖的過程。還記得以前寫過一個生產者——消費者的例項,那時候對一些問題還不是很理解。下面是一個簡單的練習例項,以及最後總結遇到的一些問題。
互斥量和條件變數
1、如何利用2個條件變數實現執行緒同步? 思路:就是來回的利用pthread_cond_signal()函式,當一方被阻塞時,喚醒函式可以喚醒pthread_cond_wait()函式,只不過pthread_cond_wait()這個方法要執行其後的語句,必須遇到下一個阻塞
windows 使用關鍵段和條件變數實現的生產者和消費者執行緒同步
關鍵段比較簡單,呼叫函式如下: VOID InitializeCriticalSection( LPCRITICAL_SECTION );//初始化一個關鍵程式碼段 VOID EnterCriticalSection( LPCRITICAL_SECTION);//獲取
linux 各個目錄和相關文件的作用等 (混亂版)初學者自用
nac 歷史 沒有 The 用戶配置 相關 file 文件 prot t權限 /etc/profile文件當一個用戶登陸linux系統或者使用su命令切換到另一個用戶時,也就是login shell啟動時首先要保證執行的啟動腳本就是/etc/profile ??/etc/
[Linux]通過使用者名稱和密碼的方式搭建Git伺服器(http&gitweb)
1、安裝依賴 yum -y install perl cpio autoconf tk zlib-devel libcurl-devel openssl-devel expat-devel yum install perl-ExtUtils-CBuilder
Linux多執行緒程式設計---執行緒間同步(互斥鎖、條件變數、訊號量和讀寫鎖)
本篇博文轉自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了多種方式來處理執行緒同步,最常用的是互斥鎖、條件變數、訊號量和讀寫鎖。 下面是思維導