本文出自https://shuwoom.com博客,歡迎訪問!
互斥
簡單地理解就是,一個線程進入工作區後,如果有其他線程想要進入工作區,它就會進入等待狀態,要等待工作區內的線程結束後纔可以進入。
基本函數
(1) pthread_mutex_init函數
原型:int pthread_mutex_init ( pthread_mutex_t *mutex, const pthread_mutexattr_t* attr);
描述:設置互斥量的屬性
參數:第一個參數:預先聲明的pthread_mutex_t對象指針
第二個參數:互斥鎖屬性,NULL表示使用默認屬性
返回值:成功時返回0, 失敗時返回一個錯誤代碼
(2) pthread_mutex_lock函數
原型:int pthread_mutex_lock ( pthread_mutex_t *mutex );
描述:pthread_mutex_lock返回時,互斥鎖被鎖定,如果這個互斥鎖被一個線程鎖定和擁有,那麼另一個線程要調用這 個函數會進入堵塞狀態(即等待狀態),直到互斥鎖被釋放爲止。
返回值:成功時返回0, 失敗時返回一個錯誤代碼
(3) pthread_mutex_unlock函數
原型:int pthread_mutex_unlock ( pthread_mutex_t *mutex );
描述:釋放互斥鎖
返回值:成功時返回0, 失敗時返回一個錯誤代碼
(4) pthread_mutex_destroy函數
原型:int pthread_mutex_destroy ( pthread_mutex_t *mutex );
描述:刪除互斥鎖
返回值:成功時返回0, 失敗時返回一個錯誤代碼
實例
lock.c文件
描述:這個程序主要可以概括爲主線程負責接受輸入的字符串,而子線程則負責統計並輸出字符數。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void *thread_function(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;
/*初始化互斥量*/
res = pthread_mutex_init(&work_mutex, NULL);
if (res != 0) {
perror("互斥量初始化失敗!");
exit(EXIT_FAILURE);
}
/*啓動新線程*/
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("線程創建失敗");
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&work_mutex);
printf("請輸入一些文本內容. 輸入“end”結束\n");
while(!time_to_exit) {
fgets(work_area, WORK_SIZE, stdin);
pthread_mutex_unlock(&work_mutex);
while(1) {
pthread_mutex_lock(&work_mutex);
/*統計字符工作未完成*/
if (work_area[0] != '\0') {
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else {
/*統計字符工作完成,跳出內層循環,重新讀取輸入*/
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("\n等待線程結束...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}
/*主線程首先鎖定工作區,在獲取輸入的字符後,釋放工作區,讓其他線程對字符個數進行統計。work_area[0[爲空字符時表示統計結束。通過週期性地對互斥量進行加鎖,檢查是否已經統計完。*/
/*在線程中要執行的代碼*/
void *thread_function(void *arg) {
sleep(1);
pthread_mutex_lock(&work_mutex);
while(strncmp("end", work_area, 3) != 0) {
printf("你輸入了 %d 個字符\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);
pthread_exit(0);
}
/*在新線程一上來先試圖對互斥量進行加鎖。如果它已經被鎖上,新線程就會進入堵塞狀態知道互斥鎖釋放爲止,
一旦可以進入工作區,就先檢查是否有退出請求(end)如果有,就設置time_to_exit變量和work_area,然後退出程序。
如果沒有退出,那麼就對字符個數進行統計。把work_area[0]設置爲空,表示統計工作完成。接下來就釋放互斥鎖,
等待主線程的運行,週期性地給互斥量加鎖,如果加鎖成功,就檢查主線程是否又給我們新的字符串統計。如果沒有,
就釋放互斥鎖繼續等待,*/
編譯執行:gcc -D_REENTRANT fork.c -o fork -lpthread
運行結果如下:
參考文獻:Linux程序設計