二、讀寫鎖
三、條件變數
三、訊號量
同步即協同步調,按預定的先後順序執行
由於執行緒共享程序的資源和位址空間,當多個執行緒對同一共享資源進行操作時,為防止資料混亂,因此在對這些資源進行操作時,必須考慮到執行緒間資源訪問的同步和互斥的問題。這裡介紹 posix 中線程同步的方法,主要有互斥鎖、讀寫鎖、條件變數和訊號量的方式。互斥鎖更適合用於同時可用的資源是唯一的情況;訊號量更適合用於同時可用的資源為多個情況
資料混亂的原因
資源共享(獨享資源則不會)
排程隨機(意味著資料訪問會出現競爭)
執行緒間缺乏必要的同步機制
mutex 是一種簡單的加鎖的方法來控制對共享資源的訪問。這個互斥鎖只有兩種狀態,也就是上鎖和解鎖,可以把互斥鎖看作某種意義上的全域性變數。在同一時刻只能有乙個執行緒掌握某個互斥上的鎖,擁有上鎖狀態的執行緒能夠對共享資源進行操作。若其他執行緒希望對共享資料操作就需要先拿到互斥鎖,若該鎖已經被另乙個執行緒擁有,則該執行緒就會掛起,直到上鎖的執行緒釋放掉互斥鎖為止。
注意:互斥鎖為建議鎖,即建議程式中的多執行緒訪問共享資料的時候使用該機制,但並沒有強制限定,所以既是有了mutex互斥鎖,若執行緒不使用該機制規則就訪問資料,依然會造成資料混亂。
互斥鎖可以分為快速互斥鎖、遞迴互斥鎖和檢錯互斥鎖。這三種鎖的區別主要在於其他未占有互斥鎖的執行緒在希望得到互斥鎖時的是否需要阻塞等待。
當pthread_mutex_init函式第二個引數設為null時,預設屬性為:快速互斥鎖
注意:在訪問共享資源前加鎖,訪問結束後立即解鎖
以上函式均是。成功:返回1; 失敗:返回錯誤碼
1.執行緒對同一互斥鎖加鎖兩次
2.執行緒1擁有a鎖,同時請求獲得b鎖
讀寫鎖與互斥鎖相識,但讀寫鎖擁有更高的並行性,其特徵為:寫獨佔,讀共享,寫鎖優先順序高
讀寫鎖一一把鎖,但是有三種狀態
int
pthread_rwlock_init
(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr)
;//初始化
intpthread_rwlock_destroy
(pthread_rwlock_t *rwlock)
;int
pthread_rwlock_rdlock
(pthread_rwlock_t *rwlock)
;//設定讀鎖
intpthread_rwlock_tryrdlock
(pthread_rwlock_t *rwlock)
;//嘗試獲取讀出鎖
intpthread_rwlock_wrlock
(pthread_rwlock_t *rwlock)
;//設定寫鎖
intpthread_rwlock_unlock
(pthread_rwlock_t *rwlock)
;//設定解鎖
pthread_rwlock_t 型別,用於定義乙個讀寫鎖變數
第二個引數:attr表示讀寫鎖的屬性,通常使用預設屬性,傳null即可
以上函式,成功:返回0,失敗:返回錯誤號
條件變數本身不是鎖,但是它可以造成執行緒阻塞,通常與互斥鎖配合使用,給多執行緒提供乙個回合場所
int
pthread_cond_init
(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr)
;//初始化條件變數
intpthread_cond_destroy
(pthread_cond_t *cond)
;int
pthread_cond_timedwait
(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex,
const
struct timespec *restrict abstime)
;int
pthread_cond_wait
(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
;//阻塞等待條件變數
intpthread_cond_signal
(pthread_cond_t *cond)
;//發出資訊喚醒某個阻塞執行緒
intpthread_cond_broadcast
(pthread_cond_t *cond)
;//喚醒所有阻塞執行緒
pthread_cond_t型別,用於定義乙個條件變數
第二個引數:attr表示條件變數的屬性,通常使用預設屬性,傳null即可
以上函式,成功:返回0,失敗:返回錯誤號
訊號量是互斥鎖的進化版。即可應用於執行緒也可應用於程序
訊號量,是一種相對折中的處理方式,既能保證同步,資料不混亂,又能提高執行緒併發
int
sem_init
(sem_t *sem,
int pshared,
unsigned
int value)
;//初始化訊號量
intsem_wait
(sem_t *sem)
;int
sem_trywait
(sem_t *sem)
;int
sem_timedwait
(sem_t *sem,
const
struct timespec *abs_timeout)
;int
sem_post
(sem_t *sem)
;//它將訊號量的值加一同時發出訊號喚醒等待的程序。
intsem_getvalue
(sem_t *sem,
int*sval)
;//由於得到訊號量的值
intsem_destroy
(sem_t *sem)
;//用於刪除訊號量
sem_t型別,定義訊號量
pshared:
值為0,執行緒間同步
值為非0,程序間同步
value:訊號量初始化值,它的大小決定了占用訊號量的執行緒的個數
返回值:成功:返回0,失敗:返回-1
Linux 執行緒同步2
讀寫鎖與互斥鎖類似,不過讀寫鎖允許更高的並行性。讀寫鎖可以有三種狀態 1 讀模式下的加鎖狀態 2 寫模式下的加鎖狀態 3 不加鎖狀態。這個區別與互斥鎖的,因為互斥鎖只有加鎖和不加鎖的兩種狀態。一次只能有乙個執行緒的寫狀態的讀寫鎖,但是可以有多個執行緒占有讀狀態的讀寫鎖。include int pth...
Linux多執行緒程式設計(2)執行緒同步
執行緒同步 a.mutex 互斥量 多個執行緒同時訪問共享資料時可能會衝突,這跟前面講訊號時所說的可重要性是同樣的問 題。假如 兩個執行緒都要把某個全域性變數增加1,這個操作在某平台需要三條指令完成 1.從記憶體讀變數值到暫存器 2.暫存器的值加1 3.將暫存器的值寫回記憶體 我們通過乙個簡單的程式...
linux 執行緒 執行緒同步
因為執行緒獨自擁有的只有棧,其他的區域執行緒共同擁有。並且對共享區域的操作並不都是原子的。對共享區域的操作順序又是不確定的。就像建立兩個檔案描述符同時指向 同一檔案,並且連續向檔案中寫入那麼寫的東西可能是亂七八糟的。這時就需要執行緒對共享區的同步。而另一種情況是,多個執行緒的指令執行順序需要同步。這...