【Linux】互斥量

1.簡介:

在代碼運行過程中,當兩個線程同時使用一個變量X:初值爲10,比如A線程在作X=X-1 ,B線程在X=X+1;那麼有可能,A線程X-1=9,切到了B線程,此時X+1=10,那麼程序切回A線程後X=10;離開線程A之前X = 9,回到線程A時X= 10;明顯X的值對A線程來說是異常的,這不是我們期望程序的運行邏輯。於是產生了互斥量。

2.互斥量簡單用法:

在線程A中,互斥量上鎖之後,變量X僅僅可以被線程A修改值。而線程B無法修改X的值,當A線程關於X的邏輯運行完了之後,互斥量解鎖,變量X纔可以被線程B所修改調用。這樣確保了線程A的正常運行。

在互斥量作用下,可以保證每個線程使用共用數據的時候,不會因爲其他線程修改了這個值,而導致運行異常。總之:互斥量是爲了保證多線程共用數據的準確性。在實際寫代碼中,不希望某個變量在某段代碼被其他線程修改,則可以上鎖,用完之後,在解鎖。

3.常用函數:

//創建互斥量
int pthread_mutext_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

//鎖住互斥量
int pthread_mutex_lock(pthread_mutex_t *mutex);

//解鎖互斥量
int pthread_mutex_trylock(pthread_mutex_t *mutex);

//銷燬互斥量
int pthread_mutex_destroy(pthread_mutex_t *mutex);

 4.簡單示例

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "semaphore.h"

void *thread_funtion(void *arg);
pthread_mutex_t work_mutex;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;

int main()
{
    int res;
    pthread_t a_thread;
    void *thread_result;

    //1.創建互斥量
    res = pthread_mutex_init(&work_mutex, NULL);
    if(res != 0) { printf("erro mutex creat"); }

    res = pthread_create(&a_thread, NULL, thread_funtion, NULL);
    if(res != 0){  printf("error create thread");  }


    pthread_mutex_lock(&work_mutex); //鎖定使用權
    printf("please press keyborad!!! end with button 'end'\r\n ");
    while(!time_to_exit)
    {
	    fgets(work_area, WORK_SIZE, stdin);//輸入字符
        pthread_mutex_unlock(&work_mutex);//釋放使用權給線程A

        while(1)
        {
            pthread_mutex_lock(&work_mutex);//若線程A未釋放權限,將在此處阻塞
            if(work_area[0] != '\0')
            {
                pthread_mutex_unlock(&work_mutex);//權限給到線程A
                sleep(1);
            }
            else {  break;  }
        }
    
    }

    //4.等待線程結束
    printf("\n thread waiting for finish \n"); 
    res = pthread_join(a_thread, &thread_result);//thread_result == Thread_A return  "Thank you using CPU!!!!!!"
    if(res != 0){  printf("error thread join "); }
    printf("thread joined, it returned %s ", (char*)thread_result);

    //5.銷燬信號量
    pthread_mutex_destroy(&work_mutex);

}


void *thread_funtion(void* arg)
{
    printf("111\n");
    sleep(1);

    pthread_mutex_lock(&work_mutex);//若主線程未釋放權限,將在此阻塞
    printf("222");
    while(strncmp("end", work_area, 3) != 0)
    {   
        printf("you have input %zu characters\n", strlen(work_area)-1); //
        work_area[0]= '\0';
        pthread_mutex_unlock(&work_mutex);//釋放權限

        sleep(1);
        pthread_mutex_lock(&work_mutex);
        while(work_area[0] == '\0')
        {
            pthread_mutex_unlock(&work_mutex);
            sleep(1);
            pthread_mutex_lock(&work_mutex);  
        }
    }
    time_to_exit = 1;
    work_area[0]= '\0';
    pthread_mutex_unlock(&work_mutex);
    printf("333");
}

 

5.基本分析:

【1】創建互斥量,創建線程A(thread_function() )。在main()中上鎖,即代表此時共有數據(數組work_area)只有主線程(main())可以修改,然後程序運行至打印please press keyborad,

【2】同時程序也運行至線程A(打印了111), 但主線程(main)已經上了鎖,線程A的程序則會在此處阻塞(沒有打印222)

【3】運行至主線程的fget()函數,用戶鍵盤輸入字符abc,並且線程A擁有了權限。

【4】線程A擁有了權限,退出阻塞(打印了222和you have input 3 charcters)

【5】輸入end,主線程和線程A退出while(打印了333和thread waiting for finish)。

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