11 6 執行緒 執行緒同步

2021-05-22 14:22:01 字數 2654 閱讀 1431

除了計算機體系結構的因素以外,程式使用變數的方式也會引起競爭,也會導致不一致的情況發生。例如,可能會對某個變數加1,然後基於這個數值做出某種決定。增量操作這一步和做出決定這一步兩者的組合並非原子操作,因而給不一致情況提供了可能。

1.互斥量

可以通過使用pthread的互斥介面保護資料,確保同一時間只有乙個執行緒訪問資料。互斥量(mutex)從本質上說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。對互斥量進行加鎖以後,任何其他試圖再次對互斥量加鎖的執行緒將會被阻塞直到當前執行緒釋放該互斥鎖。在設計時需要規定所有的執行緒必須遵守相同的資料訪問規則,只有這樣,互斥機制才能正常工作。

返回值:若成功則返回0,否則返回錯誤編號

互斥變數用pthread_mutex_t資料型別來表示,在使用互斥變數以前,必須首先對它進行初始化,可以把它置為常量pthread_mutex_initializer(只對靜態分配的互斥量),也可以通過呼叫pthread_mutex_init函式進行初始化。如果動態地分配互斥量(例如通過呼叫malloc函式),那麼在釋放記憶體前需要呼叫pthread_mutex_destroy。要用預設的屬性初始化互斥量,只需把attr設定為null。

返回值:若成功則返回0,否則返回錯誤編號

對互斥量進行加鎖,需要呼叫pthread_mutex_lock,如果互斥量已經上鎖,呼叫執行緒將阻塞直到互斥量被解鎖。對互斥量解鎖,需要呼叫pthread_mutex_unlock。如果執行緒不希望被阻塞,它可以使用pthread_mutex_trylock嘗試對互斥量進行加鎖。如果呼叫pthread_mutex_trylock時互斥量處於未鎖住狀態,那麼pthread_mutex_trylock將鎖住互斥量,不會出現阻塞並返回0,否則pthread_mutex_trylock就會失敗,不能鎖住互斥量,而返回ebusy。

2.避免死鎖

如果執行緒試圖對同乙個互斥量加鎖兩次,那麼它自身就會陷入死鎖狀態。可以通過小心地控制互斥量加鎖的順序來避免死鎖的發生。只有在乙個執行緒試圖以另乙個執行緒相反的順序鎖住互斥量時,才可能出現死鎖。也可以使用pthread_mutex_trylock介面避免死鎖。如果已經占有某些鎖而且pthread_mutex_trylock介面返回成功,那麼就可以前進;但是,如果不能獲取鎖,可以先釋放已占有的鎖,做好清理工作,然後過一段時間重新嘗試。

多執行緒的軟體設計經常要考慮以下的折中處理方案。如果鎖的粒度太粗,就會出現很多執行緒阻塞等待相同的鎖,源自併發性的改善微乎其微。如果鎖的粒度太細,那麼過多的鎖開銷會使系統效能受到影響,而且**變得相當複雜。作為乙個程式設計師,需要在滿足鎖需求的情況下,在**發雜性和優化性之間找好平衡點。

3.讀寫鎖

讀寫鎖與互斥量類似,不過讀寫鎖允許更高的並行性。互斥量要麼是鎖住狀態要麼是不加鎖狀態,而且一次只有乙個執行緒可以對其加鎖。讀寫鎖可以有三種狀態:讀模式下的加鎖狀態,寫模式下的加鎖狀態,不加鎖狀態。一次只有乙個執行緒可以占有寫模式的讀寫鎖,但是多個執行緒可以同時占有讀模式的讀寫鎖。

當讀寫鎖是寫加鎖狀態時,在這個鎖被解鎖之前,所有試圖對這個鎖加鎖的執行緒都會被阻塞。當讀寫鎖在讀加鎖狀態時,所有試圖以讀模式對它進行加鎖的執行緒都可以得到訪問權,但是如果執行緒希望以寫模式對此鎖進行加鎖,它必須阻塞知道所有的執行緒釋放讀鎖。

讀寫鎖非常適合於對資料結構讀的次數遠大於寫的情況。讀寫鎖也叫共享-獨佔鎖,當讀寫鎖以讀模式鎖住時,它是以共享模式鎖住的,當它以寫模式鎖住時,它是以獨佔模式鎖住的。

返回值:若成功返回0,否則返回錯誤編號

與互斥量一樣,讀寫鎖在使用之前必須初始化,在釋放它們底層的記憶體前必須銷毀。如果希望讀寫鎖有預設的屬性,可以傳乙個空指標給attr。

返回值:若成功返回0,否則返回錯誤編號

要在讀模式下鎖定讀寫鎖,需要呼叫pthread_rwlock_rdlock;要在寫模式下鎖定讀寫鎖,需要呼叫pthread_rwlock_wrlock。不管以何種方式鎖住讀寫鎖,都可以呼叫pthread_rwlock_unlock進行解鎖。

返回值:若成功返回0,否則返回錯誤ebusy

4.條件變數

條件變數給多個執行緒提供了乙個會合的場所。條件變數與互斥量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。條件本身是由互斥量保護的。執行緒在改變條件狀態前必須首先鎖住互斥量。

返回值:若成功返回0,否則返回錯誤編號

除非需要建立乙個非預設屬性的條件變數,否則pthread_cond_init函式的attr引數可以設定為null。

返回值:若成功返回0,否則返回錯誤編號

使用pthread_cond_wait等待條件變為真,如果在給定的時間內條件不能滿足,那麼會生成乙個代表出錯碼的返回變數。傳遞給pthread_cond_wait的互斥量對條件進行保護,呼叫者把鎖住的互斥量傳給函式。函式把呼叫執行緒放到等待條件的執行緒列表上,然後對互斥量解鎖,這兩個操作是原子操作。pthread_cond_wait返回時,互斥量再次被鎖住。

pthread_cond_timedwait函式的工作方式與pthread_cond_wait函式相似,只是多了乙個timeout。timeout值指定了等待的時間,它是通過timespec結構指定。時間值是乙個絕對數而不是相對數。如果時間值到了但是條件還是沒有出現,pthread_cond_timewait將重新獲取互斥量然後返回錯誤etimedout。

返回值:若成功返回0,否則返回錯誤編號

這兩個函式可以用於通知執行緒條件已經滿足。int pthread_cond_signal函式將喚醒等待該條件的某個執行緒,而int pthread_cond_broadcast函式將喚醒等待該條件的所有執行緒。

同步 執行緒同步

操作執行的先後順序。同步指兩個或兩個以上隨時間變化的量在變化過程中保持一定的相對關係。同步 英語 synchronization 指對在乙個系統中所發生的事件 event 之間進行協調,在時間上出現一致性與統一化的現象。在系統中進行同步,也被稱為及時 in time 同步化的 synchronous...

linux 執行緒 執行緒同步

因為執行緒獨自擁有的只有棧,其他的區域執行緒共同擁有。並且對共享區域的操作並不都是原子的。對共享區域的操作順序又是不確定的。就像建立兩個檔案描述符同時指向 同一檔案,並且連續向檔案中寫入那麼寫的東西可能是亂七八糟的。這時就需要執行緒對共享區的同步。而另一種情況是,多個執行緒的指令執行順序需要同步。這...

執行緒同步 執行緒安全

1 執行緒同步 1 同步 多程序或者多執行緒訪問臨界資源時,必須進行同步控制。多程序或者多執行緒的執行並不完全是絕對的並行執行,有可能主線程需要等待函式執行緒的某些條件的發生。2 多執行緒之間有幾個特殊的臨界資源 全域性資料 堆區資料 檔案描述符 多執行緒之間共用 3 執行緒間同步控制方式 a.訊號...