pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
描述 pthread_mutex_lock()函數鎖住由mutex指定的mutex 對象。如果mutex已經被鎖住,調用這個函數的線程阻塞直到mutex可用為止。這跟函數返回的時候參數mutex指定的mutex對象變成鎖住狀態, 同時該函數的調用線程成為該mutex對象的擁有者。
如果mutex 對象的type是 PTHREAD_MUTEX_NORMAL,不進行deadlock detection(死鎖檢測)。企圖進行relock 這個mutex會導致deadlock. 如果一個線程對未加鎖的或已經unlock的mutex對象進行unlock操作,結果是不未知的。
如果mutex類型是 PTHREAD_MUTEX_ERRORCHECK,那麼將進行錯誤檢查。如果一個線程企圖對一個已經鎖住的mutex進行relock,將返回一個錯 誤。如果一個線程對未加鎖的或已經unlock的mutex對象進行unlock操作,將返回一個錯誤。
如果mutex類型是 PTHREAD_MUTEX_RECURSIVE,mutex會有一個鎖住次數(lock count)的概念。當一個線程成功地第一次鎖住一個mutex的時候,鎖住次數(lock count)被設置為1,每一次一個線程unlock這個mutex的時候,鎖住次數(lock count)就減1。當鎖住次數(lock count)減少為0的時候,其他線程就能獲得該mutex鎖了。如果一個線程對未加鎖的或已經unlock的mutex對象進行unlock操作,將返 回一個錯誤。
如果mutex類型是 PTHREAD_MUTEX_DEFAULT,企圖遞歸的獲取這個mutex的鎖的結果是不確定的。unlock一個不是被調用線程鎖住的mutex的結 果也是不確定的。企圖unlock一個未被鎖住的mutex導致不確定的結果。
pthread_mutex_trylock()調用在參數mutex指定的mutex對象當前被鎖住的時候立即返回,除此之外,pthread_mutex_trylock()跟pthread_mutex_lock()功能完全一樣。
pthread_mutex_unlock()函數釋放有參數mutex指定的mutex對象的鎖。如果被釋放取決於該Mutex對象的類型屬性。如果有多個線程為了獲得該mutex鎖阻塞,調用pthread_mutex_unlock()將是該mutex可用,一定的調度策略將被用來決定哪個線程可以獲得該mutex鎖。(在mutex類型為PTHREAD_MUTEX_RECURSIVE 的情況下,只有當lock count 減為0並且調用線程在該mutex上已經沒有鎖的時候)(翻譯到這裡,才覺得我的這個鎖概念是多麼模糊) 如果一個線程在等待一個mutex鎖得時候收到了一個signal,那麼在從signal handler返回的時候,該線程繼續等待該mutex鎖,就像這個線程沒有被中斷一樣。
返回值成功
pthread_mutex_lock() 和 pthread_mutex_unlock() 返回0,否則返回一個錯誤的提示碼
pthread_mutex_trylock() 在成功獲得了一個mutex的鎖後返回0,否則返回一個錯誤提示碼錯誤
pthread_mutex_lock() 和 pthread_mutex_unlock()失敗的時候 [EINVAL] mutex在生成的時候,它的protocol屬性的值是 PTHREAD_PRIO_PROTECT,同時調用線程的優先級(priority)比該mutex的當前prority上限高
pthread_mutex_trylock() 函數在一下情況會失敗:
[EBUSY] The mutex could not be acquired because it was already locked. mutex已經被鎖住的時候無法再獲取鎖
The pthread_mutex_lock(), pthread_mutex_trylock() and pthread_mutex_unlock() functions may fail if:
[EINVAL] mutex指向的mutex未被初始化
[EAGAIN] Mutex的lock count(鎖數量)已經超過 遞歸索的最大值,無法再獲得該mutex鎖
pthread_mutex_lock() 函數在一下情況下會失敗:
[EDEADLK] 當前線程已經獲得該mutex鎖
pthread_mutex_unlock() 函數在以下情況下會失敗:
[EPERM] 當前線程不是該mutex鎖的擁有者 所有的這些函數的錯誤返回值都不會是[EINTR]
互斥鎖
互斥鎖用來保證一段時間內只有一個線程在執行一段代碼。必要性顯而易見:假設各個線程向同一個文件順序寫入數據,最後得到的結果一定是災難性的。
我們先看下面一段代碼。這是一個讀/寫程序,它們公用一個緩沖區,並且我們假定一個緩沖區只能保存一條信息。即緩沖區只有兩個狀態:有信息或沒有信息。
void reader_function ( void );
void writer_function ( void );
char buffer;
int buffer_has_item=0;
pthread_mutex_t mutex;
struct timespec delay;
void main ( void ){
pthread_t reader;
/* 定義延遲時間*/
delay.tv_sec = 2;
delay.tv_nec = 0;
/* 用默認屬性初始化一個互斥鎖對象*/
pthread_mutex_init (&mutex,NULL);
pthread_create(&reader, pthread_attr_default, (void *)&reader_function), NULL);
writer_function( );
}
void writer_function (void){
while(1){
/* 鎖定互斥鎖*/
pthread_mutex_lock (&mutex);
if (buffer_has_item==0){
buffer=make_new_item( );
buffer_has_item=1;
}
/* 打開互斥鎖*/
pthread_mutex_unlock(&mutex);
pthread_delay_np(&delay);
}
}
void reader_function(void){
while(1){
pthread_mutex_lock(&mutex);
if(buffer_has_item==1){
consume_item(buffer);
buffer_has_item=0;
}
pthread_mutex_unlock(&mutex);
pthread_delay_np(&delay);
}
}