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)。