互斥鎖指代相互排斥,它是最基本的同步形式。互斥鎖用於保護臨界區,以保證任何時刻只有乙個執行緒在執行其中的**,或者任何乙個時刻只有乙個程序在執行其中的**。保護乙個臨界區的**的通常輪廓大體如下:
lock_the_mutex(...)
臨界區unlock_the_mutex(...)
posix互斥鎖被宣告為具有pthread_mutex_t 資料型別的變數。如果互斥鎖變數是靜態分配的,那麼我們可以把它初始化成常值pthread_mutex_initializer,例如:
static pthread_mutex_t lock = pthread_mutex_initializer
如果互斥鎖是動態分配的(例如通過呼叫malloc),或者分配在共享記憶體區中,那麼我們必須在執行之時通過呼叫pthread_mutex_init函式來初始化它。
下列三個函式給乙個互斥鎖上鎖和解鎖。
#include
int pthread_mutex_lock(pthread_mutex_t *mptr)
int pthread_mutex_trylock(pthread_mutex_t * nptr)
int pthread_mutex_unlock(pthread_mutex_t * mptr)
均返回:若成功返回0,若出錯返回正的e***值
如果嘗試乙個已由另外乙個執行緒鎖住的互斥鎖上鎖,那麼pthread_mutex_lock將阻塞到該互斥鎖解鎖為止。pthread_mutex_trylock是對應的非阻塞函式,如果該互斥鎖已鎖住,它就返回乙個ebusy錯誤。
儘管我們說互斥鎖保護的是臨界區,實際上保護的是在臨界區中被操縱的資料。也就是說,互斥鎖通常用於保護由多個執行緒和多個程序分享的共享資料。
(一、)生產者-消費者問題
在單個程序中有多個生產者執行緒和單個消費者執行緒。整數陣列buff含有被生產和消費的條目(也就是共享資料),在第乙個例子中,我們只關心多個生產者執行緒之間的同步。直到所有生產者執行緒都生產完成工作後,我們才啟動消費者執行緒。
其**如下:
#include#include#include#include#define maxnitems 1000
#define maxnthreads 100
int nitems;
structshared = ;
int min(const int a,const int b)
void * produce(void *arg)
shared.buff[shared.nput] = shared.nval;
shared.nput++;
shared.nval++;
pthread_mutex_unlock(&shared.mutex);
*((int *)arg) += 1;
}}void * consume(void *arg)
#endif
printf("buff[%d] = %d\n",i,shared.buff[i]);
}return (null);
}int main(int argc,char*argv)
nitems = min(atoi(argv[1]),maxnitems);
nthreads = min(atoi(argv[2]),maxnthreads);
pthread_setconcurrency(nthreads);
for(i = 0; i < nthreads; ++i)
for(i = 0; i < nthreads; ++i)
pthread_create(&tid_consume,null,consume,null);
pthread_join(tid_consume,null);
return 0;
}
其執行結果:
對比上鎖與等待:
現在展示互斥鎖用於上鎖而不用於等待。我們把上一節的生產者-消費者例子改為在所有生產者執行緒都啟動後立即啟動消費者執行緒。這樣在生產者執行緒產生資料的同時,消費者執行緒就能處理它,而不是像之前那樣,消費者執行緒直到所有生產者執行緒都完成後才啟動。下面給出具體的**:
#include#include#include#include#define maxnitems 1000
#define maxnthreads 100
int nitems;
structshared = ;
int min(const int a,const int b)
void * produce(void *arg)
shared.buff[shared.nput] = shared.nval;
shared.nput++;
shared.nval++;
pthread_mutex_unlock(&shared.mutex);
*((int *)arg) += 1;
}}void consume_wait(int i)
pthread_mutex_unlock(&shared.mutex);
}}void * consume(void *arg)
return (null);
}int main(int argc,char*argv)
nitems = min(atoi(argv[1]),maxnitems);
nthreads = min(atoi(argv[2]),maxnthreads);
pthread_setconcurrency(nthreads + 1);
for(i = 0; i < nthreads; ++i)
pthread_create(&tid_consume,null,consume,&count[i]);
for(i = 0; i < nthreads; ++i)
pthread_join(tid_consume,null);
return 0;
}
上述就是對互斥鎖的一些基本的應用。。。 執行緒間同步機制 互斥鎖
互斥以排他方式防止共享資料被併發修改。互斥量從本質來說是一把鎖,是乙個二元變數,其狀態為開鎖 允許0 和上鎖 禁止1 在訪問共享資源前對互斥量進行設定 加鎖 在訪問完成後釋放 解鎖 互斥量。1 在訪問該資源前,首先申請該互斥鎖,如果該互斥鎖處於開鎖狀態,則申請到該鎖物件,並立即占有該鎖 使該鎖處於鎖...
執行緒管理 互斥量同步機制
互斥量機制 在計算機系統中有許多共享資源不允許使用者並行使用,像印表機這樣的共享裝置被稱為 排它性資源 因為它一次只能由乙個執行流訪問。執行流必須以互斥的方式 執行訪問排它性資源的 互斥量 mutex 又稱為互斥鎖,是一種用來保護臨界區的特殊變數,它可以處於鎖定 locked 狀態,也可以處於解鎖 ...
執行緒同步機制之互斥量
一 互斥量的概念 互斥量 mutex 從概念上來說類似於乙個二進位制訊號量,即初始值為1的訊號量。互斥量被獲取之後就不能再被獲取,因此對互斥體的獲取和釋放操作常常稱為加鎖和解鎖操作。互斥量只能由獲取它的執行緒進行釋放,如果違反這一原則,則結果是未定義的。互斥量從本質上說是一把鎖,在訪問共享資源前對互...