在前面的文章中提及到,一個進程中的多個線程是共用同一段資源的,由於線程對資源的競爭引出了鎖。其中mutex是一種簡單的加鎖方法,這個互斥鎖只有兩種狀態,那就是上鎖和解鎖,可以把互斥鎖看作是某種意義上的全域變數。在某一時刻,只能有一個線程取得這個互斥上的鎖,擁有上鎖狀態的線程可以對共用資源進行操作,而其他線程在該線程未解鎖之前,夠會被掛起,直到上鎖的線程解開鎖。可以這麼說,互斥鎖使得共用資源按序的在各個線程上操作。
互斥鎖的操作主要包括互斥鎖初始化、上鎖、判斷上鎖、解鎖、摧毀互斥鎖。其中互斥鎖可以分為快速互斥鎖、遞迴互斥鎖這檢錯互斥鎖。這三種鎖的區別主要在於其他未佔有互斥鎖的線程在希望得到互斥鎖時是否需要等待掛起。快速鎖是指調用線程會阻塞直到線程鎖得到解鎖為止。遞迴鎖能夠成功地返回並且增加調用線程在互斥上的加鎖次數,比如一個鏈表在進行插入的操作時,可以進行尋找的操作。檢錯鎖則為快速互斥鎖的非阻塞版本,它會立即返回並返回一個錯誤的資訊。
1、函數簡義。
(1)pthread_mutex_init
標頭檔: <pthread.h>
函數原型: int pthread_mutex_init (pthread_mutex_t* mutex,
const pthread_mutexattr_t* mutexattr);
函數傳入值: mutex:互斥鎖。
mutexattr:PTHREAD_MUTEX_INITIALIZER:建立快速互斥鎖。
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:建立遞迴互斥鎖。
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:建立檢錯互斥鎖。
函數傳回值: 成功:0
出錯:-1
(2)上鎖函數:
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_trylock (pthread_mutex_t* mutex);
int pthread_mutex_unlock (pthread_mutex_t* mutex);
int pthread_mutex_destroy (pthread_mutex_t* mutex);
函數傳入值: mutex:互斥鎖。
函數傳回值: 同上。
2、互斥鎖實現。
include <stdio.h><br />#include <stdlib.h><br />#include <pthread.h><br />#include <errno.h><br />#include <unistd.h> </p><p>#define return_if_fail(p) /<br />if((p) == 0){printf("[%s]:func error!/n",__func__);return;} </p><p>typedef struct _PrivInfo<br />{<br /> pthread_mutex_t mutex;<br /> int lock_var;<br /> time_t end_time;<br />}PrivInfo; </p><p>static void info_init (PrivInfo* thiz);<br />static void* pthread_func_1 (PrivInfo* thiz);<br />static void* pthread_func_2 (PrivInfo* thiz); </p><p>int main (int argc, char** argv)<br />{<br /> pthread_t pt_1 = 0;<br /> pthread_t pt_2 = 0;<br /> int ret = 0;<br /> PrivInfo* thiz = NULL; </p><p> thiz = (PrivInfo*)malloc (sizeof (PrivInfo));<br /> if (thiz == NULL)<br /> {<br /> return -1;<br /> } </p><p> info_init(thiz); </p><p> ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);<br /> if (ret != 0)<br /> {<br /> perror ("pthread_1_create:");<br /> } </p><p> ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);<br /> {<br /> perror ("pthread_2_create:");<br /> } </p><p> pthread_join (pt_1, NULL);<br /> pthread_join (pt_2, NULL); </p><p> pthread_mutex_destroy (&thiz->mutex); </p><p> free (thiz);<br /> thiz = NULL; </p><p> return 0;<br />} </p><p>static void info_init (PrivInfo* thiz)<br />{<br /> return_if_fail (thiz != NULL); </p><p> thiz->lock_var = 0;<br /> thiz->end_time = time (NULL) + 10; </p><p> pthread_mutex_init (&thiz->mutex, NULL); </p><p> return;<br />} </p><p>static void* pthread_func_1 (PrivInfo* thiz)<br />{<br /> return_if_fail (thiz != NULL); </p><p> int i = 0;<br /> int ret = 0; </p><p> while (time (NULL) < thiz->end_time)<br /> {<br /> ret = pthread_mutex_lock (&thiz->mutex);<br /> if (ret != 0)<br /> {<br /> perror ("[%s]pthread_mutex_lock");<br /> }<br /> else<br /> {<br /> printf ("pthread1:pthread1 lock the variable!/n");<br /> } </p><p> for (i = 0; i < 2; i++)<br /> {<br /> sleep (1);<br /> thiz->lock_var ++;<br /> } </p><p> ret = pthread_mutex_unlock (&thiz->mutex);<br /> if (ret != 0)<br /> {<br /> perror ("[%s]pthread_mutex_unlock");<br /> }<br /> else<br /> {<br /> printf ("pthread1: pthread1 unlock the variable./n");<br /> }<br /> } </p><p> return;<br />} </p><p>static void* pthread_func_2 (PrivInfo* thiz)<br />{<br /> return_if_fail (thiz != NULL); </p><p> int ret = 0; </p><p> while (time (NULL) < thiz->end_time)<br /> {<br /> ret = pthread_mutex_trylock (&thiz->mutex);<br /> if (ret == EBUSY)<br /> {<br /> printf ("pthread2:the variable is locked by thread1./n");<br /> }<br /> else<br /> {<br /> if (ret != 0)<br /> {<br /> perror ("[%s]pthread2_mutex_trylock");<br /> }<br /> else<br /> {<br /> printf ("pthread2: pthread2 lock the variable./n");<br /> } </p><p> ret = pthread_mutex_unlock (&thiz->mutex);<br /> if (ret != 0)<br /> {<br /> perror ("[%s]pthread_mutex_lock");<br /> } </p><p> sleep (3);<br /> }<br /> }<br />}
在上例的中,是對變數lock_var的讀寫進行加鎖,線程一是對其進行寫,在寫的時候,線程二不能對其進行讀。直到線程一解鎖,線程二得到互斥鎖,才能進行讀。同樣,線上程二進行讀的時候,線程一不能進行寫。
今天講述到這裡,下一篇文章將講述怎樣通過訊號量來達到互斥鎖的效果。
~~END~~