線程同步1 ------ 互斥鎖

      和多進程相比,多線程的最大特點就是資源的共享。然而共享卻涉及到一個同步的問題,這是多線程編程的難點。Linux系統提供了多種方式處理線程間的同步問題,主要有互斥鎖、條件變量和異步信號。本文先講互斥鎖。


      互斥鎖通過鎖機制來實現線程間的同步。在同一個時刻,只允許一個線程執行一個關鍵部分的代碼。

      使用互斥鎖前必須對其進行初始化。有以下2種方式:

  1. 將宏結構常量PTHREAD_MUTEX_INITIALIZER賦給互斥鎖。pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER。
  2. 另外是通過pthread_mutex_init函數初始化互斥鎖。

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

      

      mutexattr表示互斥鎖的屬性,如果爲NULL使用默認屬性。


      初始化後,就可以給互斥鎖加鎖了。加鎖的2個函數是:pthread_mutex_lock()和pthread_mutex_trylock()。它們的原型如下:

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);

      用lock加鎖時,如果mutex已經被鎖住,當前嘗試加鎖的線程就會阻塞,直到互斥鎖被其他線程釋放。當加鎖函數返回時,則說明互斥鎖已經被當前線程成功加鎖。trylock函數則不同,如果mutex已經被加鎖,它會立即返回,錯誤碼爲EBUSY,而不會阻塞。

      

      pthread_mutex_unlock用來解鎖,其原型爲:

int pthread_mutex_unlock(pthread_mutex_t *mutex);


      解鎖要滿足兩個條件:一是互斥鎖必須處於加鎖的狀態;二是解鎖的線程也必須是當初加鎖的線程。解鎖後如果有其他線程在等待互斥鎖,則等待隊列中的第一個線程將獲得互斥鎖。


      互斥鎖使用完畢後,必須進行清除。清除互斥鎖使用函數pthread_mutex_destroy,該函數原型爲:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

      清除鎖時要求鎖處於開放的狀態,清除成功返回0;否則函數返回EBUSY。


      以下例子演示通過互斥鎖對全局變量在2個線程之間進行同步:

#include <stdio.h>
#include <pthread.h>

//聲明鎖和全局變量
pthread_mutex_t number_mutex;
int globalnumber;

//線程1
void thread1()
{
	//對全局變量加值5次
    int i=5;
    while(i-->0){
        pthread_mutex_lock(&number_mutex);//加鎖
        globalnumber++;
        printf("Thread 1 added,globalnumber= %d\n",globalnumber);
        pthread_mutex_unlock(&number_mutex);//解鎖
        sleep(1);
    }
}

//線程2
void thread2()
{
	//對全局變量加值3次
    int i=3;
    while(i-->0){
        pthread_mutex_lock(&number_mutex);//加鎖
        globalnumber++;
        printf("Thread 2 added,globalnumber= %d\n",globalnumber);
        pthread_mutex_unlock(&number_mutex);//解鎖
        sleep(2);
    }
}

main()
{
    pthread_t thid1,thid2;
    printf("This is Main Thread.\n");

	//互斥鎖的初始化
	pthread_mutex_init(&number_mutex,NULL);

    pthread_create(&thid1,NULL,thread1,NULL);
    pthread_create(&thid2,NULL,thread2,NULL);

    int status1,status2;
    pthread_join(thid1,(void*)&status1);
    pthread_join(thid2,(void*)&status2);

	//互斥鎖的清除
	pthread_mutex_destroy(&number_mutex);

	//等待上述2個子線程運行結束,最後再講2個子線程操作完畢的全局變量打印到屏幕
    printf("globalnumber is: %d\n",globalnumber);
    printf("Main Thread exit\n");
}

運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章