linux多執行緒-----同步機制(互斥量、讀寫鎖、條件變數)
linux多執行緒同步機制主要有:互斥量,讀寫鎖,條件變數。
互斥量:
互斥量用pthread_mutex_t資料型別表示,在使用互斥變數以前,必須對它進行初始化,可以把它設定為PTHREAD_MUTEX_INITIALIZER(只是針對靜態分配的互斥量),pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
也可以通過函式int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);進行初始化。
pthread_mutex_destroy destroys a mutex object, freeing the resources it might hold. The mutex must be unlocked on entrance.
In the LinuxThreads implementation, no resources are associated with mutex objects, thus pthread_mutex_destroy actually does
nothing except checking that the mutex is unlocked.
man手冊關於pthread_mutex_destroy的介紹就是說在linux下執行緒的實現沒有關於互斥量物件的資源,所以pthread_mutex_destroy僅僅是確認一下互斥量mutex是處於解鎖的狀態。
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
2.pthread_mutex_unlock函式是對互斥量mutex進行解鎖。
3.pthread_mutex_trylock函式嘗試對互斥量mutex進行加鎖,如果互斥量mutex處於未被鎖住的狀態,則將鎖住該互斥量並返回0。如果互斥量mutex處於鎖住的狀態,則不能鎖住該互斥量並返回EBUSY。
例子1:對互斥量加上引用計數機制,自己構造結構體。當最後一個引用被釋放的時候,物件所佔用空間也被釋放。如下所示:
/*************************************************************************
> File Name: mutex_11_5.c
> Author:
> Mail:
> Created Time: 2016年03月23日 星期三 20時41分26秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct foo{
int f_count;
pthread_mutex_t f_lock;
};
//建立並初始化一個帶有引用計數的互斥量
struct foo * foo_alloc(void)
{
struct foo * fp;
if((fp = malloc(sizeof(struct foo))) != NULL){
fp->f_count = 1;
if(pthread_mutex_init(&fp->f_lock, NULL) != 0){
free(fp);
return NULL;
}
}
return fp;
}
//對互斥量增加一個引用計數
void foo_hold(struct foo* fp)
{
pthread_mutex_lock(&fp->f_lock);
fp->f_count++;
pthread_mutex_unlock(&fp->f_lock);
}
//對互斥量減少一個引用計數
void foo_rele(struct foo* fp)
{
pthread_mutex_lock(&fp->f_lock);
if(--fp->f_count == 0){//最後一個引用了
printf("last the reference\n");
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
}
else{
pthread_mutex_unlock(&fp->f_lock);
}
}
int main()
{
struct foo * fp;
if((fp = foo_alloc()) == NULL){
printf("foo_alloc error\n");
return -1;
}
printf("After foo_alloc, the fp->f_count = %d\n", fp->f_count);
foo_hold(fp);
printf("After foo_hold, the fp->f_count = %d\n", fp->f_count);
foo_hold(fp);
printf("After foo_hold, the fp->f_count = %d\n", fp->f_count);
foo_rele(fp);
printf("After foo_rele, the fp->f_count = %d\n", fp->f_count);
foo_rele(fp);
printf("After foo_rele, the fp->f_count = %d\n", fp->f_count);
foo_rele(fp);
printf("After foo_rele, the fp->f_count = %d\n", fp->f_count);
return 0;
}
輸出:
After foo_alloc, the fp->f_count = 1
After foo_hold, the fp->f_count = 2
After foo_hold, the fp->f_count = 3
After foo_rele, the fp->f_count = 2
After foo_rele, the fp->f_count = 1
last the reference
After foo_rele, the fp->f_count = 0
讀寫鎖(也叫做共享-獨佔鎖):
讀寫鎖和互斥鎖類似,但是讀寫鎖允許更高的併發性。互斥鎖只有兩種狀態:加鎖狀態、不加鎖狀態;
讀寫鎖有三種狀態:讀模式下加鎖狀態,寫模式下加鎖狀態,不加鎖狀態;
一次只能有一個執行緒佔有寫模式下的讀寫鎖,但是可以允許多個執行緒佔用讀模式下的讀寫鎖。
讀寫鎖非常適用於對資料結構讀的次數遠大於寫的情況。
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//對讀寫鎖進行初始化
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);//釋放為讀寫鎖分配的資源
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//在讀模式下獲得讀寫鎖
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//在寫模式下獲得讀寫鎖
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//嘗試在讀模式下獲得讀寫鎖
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//嘗試在寫模式下獲得讀寫鎖
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//對讀寫鎖進行解鎖
條件變數:
條件變數是執行緒可以使用的另一種同步機制。條件變數與互斥量一起使用的時候,允許執行緒以無競爭的方式等待特定的條件發生。條件本身是由互斥量保護的。執行緒在改變條件變數狀態前必須先鎖住互斥量。
條件變數在使用前必須初始化,一種是靜態初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
另一種是動態分配的條件變數,則用pthread_cond_init函式進行初始化。
在釋放底層的記憶體空間之前,可以使用pthread_cond_destroy對條件變數進行去初始化。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);//喚醒等待該條件變數上的某個執行緒
int pthread_cond_broadcast(pthread_cond_t *cond);//喚醒等待該條件變數上的所有執行緒
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
執行緒呼叫pthread_cond_wait這個函式之後,核心會做下面這些事:
1,拿到鎖的執行緒,把鎖暫時釋放;
2,執行緒休眠,進行等待;
3,執行緒等待通知,要醒來。(重新獲取鎖)
pthread_cond_timedwait函式功能和pthread_cond_wait類似,只是多了一個等待時間abstime的限制。
條件變數的使用參考部落格:Linux多執行緒消費者和生產者模型例項(互斥鎖和條件變數使用)
相關文章
- Linux Qt使用POSIX多執行緒條件變數、互斥鎖(量)LinuxQT執行緒變數
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- 多執行緒(2)-執行緒同步互斥鎖Mutex執行緒Mutex
- 執行緒同步與互斥:互斥鎖執行緒
- 多執行緒06:條件變數執行緒變數
- Java多執行緒—執行緒同步(單訊號量互斥)Java執行緒
- 物聯網學習教程——執行緒同步與互斥:讀寫鎖執行緒
- Linux多執行緒的使用一:互斥鎖Linux執行緒
- Linux之執行緒互斥鎖Linux執行緒
- 透過互斥鎖+條件量的方式實現同步與互斥
- 多執行緒程式設計介紹-條件變數執行緒程式設計變數
- JAVA多執行緒與鎖機制Java執行緒
- Python執行緒條件變數Condition解析Python執行緒變數
- 多執行緒與併發----讀寫鎖執行緒
- 執行緒的互斥鎖執行緒
- Linux執行緒之讀寫鎖小結Linux執行緒
- 如何使用ReentrantLock的條件變數,讓多個執行緒順序執行?ReentrantLock變數執行緒
- 執行緒同步機制執行緒
- Python執行緒專題7:條件變數Python執行緒變數
- 畫江湖之 PHP 多執行緒開發 【執行緒安全 互斥鎖】PHP執行緒
- 畫江湖之 PHP 多執行緒開發 [執行緒安全 互斥鎖]PHP執行緒
- 附個人工作程式碼 條件變數深度運用、互斥鎖+訊號量變數
- 多執行緒中使用Lock鎖定多個條件Condition的使用執行緒
- 互斥鎖與條件變數學習與應用小結變數
- JAVA多執行緒詳解(3)執行緒同步和鎖Java執行緒
- Python並行程式設計(二):多執行緒鎖機制利用Lock與RLock實現執行緒同步Python並行行程程式設計執行緒
- 執行緒鎖 -賣票機制執行緒
- java synchronize - 執行緒同步機制Java執行緒
- 執行緒同步(windows平臺):互斥物件執行緒Windows物件
- 多執行緒和多執行緒同步執行緒
- 執行緒安全: 互斥鎖和自旋鎖(10種)執行緒
- 多執行緒系列(十一) -淺析併發讀寫鎖StampedLock執行緒
- 執行緒同步機制-包裝類執行緒
- 分析.Net裡執行緒同步機制執行緒
- 建立程序,設計訊號量同步機制,實現多執行緒同步 - C語言版執行緒C語言
- python多執行緒、鎖、event事件機制的簡單使用Python執行緒事件
- 多執行緒_鎖執行緒
- C++11多執行緒程式設計(二)——互斥鎖mutex用法C++執行緒程式設計Mutex
- Java多執行緒(2)執行緒鎖Java執行緒