【C/C++多執行緒程式設計之六】pthread互斥量

Love_Hulidear發表於2014-05-02

多執行緒程式設計之執行緒同步互斥量


      Pthread是 POSIX threads 的簡稱,是POSIX的執行緒標準
         Pthread執行緒同步多個執行緒協調地,有序地同步使用共享資源【C/C++多執行緒程式設計之五】pthread執行緒深入理解中講述到,多執行緒共享程式資源,一個執行緒訪問共享資源需要一段完整地時間才能完成其讀寫操作,如果在這段時間內被其他執行緒打斷,就會產生各種不可預知的錯誤。協調執行緒按一定的規則,不受打擾地訪問共享資源,保證正確性,這便是執行緒同步的出發點。
       互斥量,是最簡單的執行緒同步機制,也是最常用的同步策略。
       
       1.互斥量mutex

       互斥量是一種執行緒同步物件,“互斥”的含義是同一時刻只能有一個執行緒獲得互斥量。一個互斥量對應一個共享資源,互斥量狀態:1.解鎖狀態意味著共享資源可用,2.加鎖狀態意味著共享資源不可用
       一個執行緒需要使用共享資源時,使用thread_mutex_lock申請:1.當互斥量為解鎖狀態,則佔用互斥量,並給互斥量加鎖,佔用資源(互相量為加鎖狀態,其他執行緒不能使用互斥量並等待互斥量變為解鎖狀態),2.如果互斥量為加鎖狀態,則執行緒等待,直到互斥量為解鎖狀態(其他執行緒使用完共享資源後會解鎖互斥量,釋放資源)。

        2.互斥量基本函式        
        #include <pthread.h>
初始化互斥量:
        int pthread_mutex_init(pthread_mutex *mutex,
                                                const pthread_mutexattr_t* mutexattr
);
        該函式第一個引數為一個互斥量指標,第二個引數為互斥量屬性指標(一般設為NULL)。該函式將按照互斥量屬性對互斥量進行初始化。
互斥量加鎖:
        int pthread_mutex_lock(pthread_mutex *mutex);
        該函式申請一個互斥量並對其進行加鎖,使該互斥量對其他執行緒不可用,讓其他申請互斥量的執行緒等待。
互斥量解鎖:
        int pthread_mutex_unlock(pthread_mutex *mutex);
        該函式對互斥量進行解鎖操作,使該互斥量對其他執行緒可以。
銷燬互斥量:
        int pthread_mutex_destroy(pthread_mutex *mutex);
        該函式銷燬一個不再需要的互斥量,釋放系統資源。
          
           3.牛刀小試
#include 
#include 
#include 
#include 
#pragma comment(lib, "pthreadVC2.lib")     //必須加上這句
pthread_t t1;           //pthread_t變數t1,用於獲取執行緒1的ID
pthread_t t2;           //pthread_t變數t2,用於獲取執行緒2的ID
char Share[10];         //共享資源區
pthread_mutex_t work_mutex;                    //宣告互斥量work_mutex
void* My_thread_1(void* args){
	while(1){
	   char *p=Share;
	   //pthread_mutex_lock(&work_mutex);      //加鎖
	   for(int i=0;i<9;i++)
	   {
	       *p='a';             //執行緒1將Share寫成aaaaaaaa
		   Sleep(100);
		   p++;
	   }
	   p++;
	   *p='\0';
	   printf("1 Share is : %s\n",Share);
	   //pthread_mutex_unlock(&work_mutex);   //解鎖
	   //Sleep(100)            //啟用互斥量時也去除註釋,為程式排程提供時間
	   }
	   return NULL;
}
void* My_thread_2(void* args){
	while(1){
	   char *p=Share;
	   //pthread_mutex_lock(&work_mutex);     //加鎖
	   for(int i=0;i<9;i++)
	   {
	       *p='e';             //執行緒1將Share寫成eeeeeeee
		   Sleep(150);
		   p++;
	   }
	   p++;
	   *p='\0';
	   printf("2 Share is : %s\n",Share);
	   //pthread_mutex_unlock(&work_mutex);   //解鎖
	   //Sleep(100)            //啟用互斥量時也去除註釋,為程式排程提供時間
	   }
	   return NULL;
}
int main(){
	   //pthread_mutex_init(&work_mutex, NULL);   //初始化互斥量
       pthread_create(&t1,NULL,My_thread_1,NULL);
	   pthread_create(&t2,NULL,My_thread_2,NULL);
       Sleep(1000000);
	   //pthread_mutex_destroy(&work_mutex);      //銷燬互斥量
       return 0;
}
              執行緒My_thread_1將共享資源字串Share寫成aaaaaaaa,執行緒My_thread_2則將其寫成eeeeeeee。
       不啟用互斥量的情況下,兩個執行緒對共享資源的訪問是隨機並且無規律,相互干擾打斷,產生a和e混合的字串,這顯然不是我們期望的結果。
       啟用互斥量(去掉註釋)情況下,互斥量機制其作用,兩個執行緒同步協調地訪問共享資源Share,產生aaaaaaaa或eeeeeeee字串,符合我們的預期。 
         通過該示例,讀者可以直觀地感受到互斥量的作用,親身體會互斥量機制,同時能讓讀者瞭解互斥量的內在原理。

相關文章