【Linux系统编程】互斥锁
00. 目錄
文章目錄
- 00. 目錄
- 01. 互斥鎖引入
- 02. 互斥鎖的操作流程
- 03. 互斥鎖相關函數
- 3.1 互斥鎖初始化
- 3.2 互斥鎖加鎖
- 3.3 互斥鎖解鎖
- 3.4 互斥鎖銷毀
- 04. 互斥鎖示例
- 05. 總結
01. 互斥鎖引入
為什么需要互斥鎖?
在多任務操作系統中,同時運行的多個任務可能都需要使用同一種資源。這個過程有點類似于,公司部門里,我在使用著打印機打印東西的同時(還沒有打印完),別人剛好也在此刻使用打印機打印東西,如果不做任何處理的話,打印出來的東西肯定是錯亂的。
下面我們用程序模擬一下這個過程,線程一需要打印“ hello ”,線程二需要打印“ world ”,不加任何處理的話,打印出來的內容會錯亂:
#include <stdio.h> #include <pthread.h> #include <unistd.h>// 打印機 void printer(char *str) {while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n"); }// 線程一 void *thread_fun_1(void *arg) {char *str = "hello";printer(str); //打印 }// 線程二 void *thread_fun_2(void *arg) {char *str = "world";printer(str); //打印 }int main(void) {pthread_t tid1, tid2;// 創建 2 個線程pthread_create(&tid1, NULL, thread_fun_1, NULL);pthread_create(&tid2, NULL, thread_fun_2, NULL);// 等待線程結束,回收其資源pthread_join(tid1, NULL);pthread_join(tid2, NULL); return 0; }測試結果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out hwoelrlldodeng@itcast:/mnt/hgfs/LinuxHome/code.bak2$實際上,打印機是有做處理的,我在打印著的時候別人是不允許打印的,只有等我打印結束后別人才允許打印。這個過程有點類似于,把打印機放在一個房間里,給這個房間安把鎖,這個鎖默認是打開的。當 A 需要打印時,他先過來檢查這把鎖有沒有鎖著,沒有的話就進去,同時上鎖在房間里打印。而在這時,剛好 B 也需要打印,B 同樣先檢查鎖,發現鎖是鎖住的,他就在門外等著。而當 A 打印結束后,他會開鎖出來,這時候 B 才進去上鎖打印。
而在線程里也有這么一把鎖——互斥鎖(mutex),互斥鎖是一種簡單的加鎖的方法來控制對共享資源的訪問,互斥鎖只有兩種狀態,即加鎖( lock )和解鎖( unlock )。
02. 互斥鎖的操作流程
1)在訪問共享資源后臨界區域前,對互斥鎖進行加鎖。
2)在訪問完成后釋放互斥鎖上的鎖。
3)對互斥鎖進行加鎖后,任何其他試圖再次對互斥鎖加鎖的線程將會被阻塞,直到鎖被釋放。
互斥鎖的數據類型是: pthread_mutex_t。
03. 互斥鎖相關函數
3.1 互斥鎖初始化
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); 功能:初始化一個互斥鎖。 參數:mutex:互斥鎖地址。類型是 pthread_mutex_t 。attr:設置互斥量的屬性,通常可采用默認屬性,即可將 attr 設為 NULL。 返回值:成功:0,成功申請的鎖默認是打開的。失敗:非 0 錯誤碼可以使用宏 PTHREAD_MUTEX_INITIALIZER 靜態初始化互斥鎖,比如:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
這種方法等價于使用 NULL 指定的 attr 參數調用 pthread_mutex_init() 來完成動態初始化,不同之處在于 PTHREAD_MUTEX_INITIALIZER 宏不進行錯誤檢查。
3.2 互斥鎖加鎖
int pthread_mutex_lock(pthread_mutex_t *mutex); 功能:對互斥鎖上鎖,若互斥鎖已經上鎖,則調用者一直阻塞,直到互斥鎖解鎖后再上鎖。 參數:mutex:互斥鎖地址。 返回值:成功:0失敗:非 0 錯誤碼int pthread_mutex_trylock(pthread_mutex_t *mutex); 調用該函數時,若互斥鎖未加鎖,則上鎖,返回 0;若互斥鎖已加鎖,則函數直接返回失敗,即 EBUSY。3.3 互斥鎖解鎖
int pthread_mutex_unlock(pthread_mutex_t * mutex); 功能:對指定的互斥鎖解鎖。 參數:mutex:互斥鎖地址。 返回值:成功:0失敗:非 0 錯誤碼3.4 互斥鎖銷毀
int pthread_mutex_destroy(pthread_mutex_t *mutex); 功能:銷毀指定的一個互斥鎖。互斥鎖在使用完畢后,必須要對互斥鎖進行銷毀,以釋放資源。 參數:mutex:互斥鎖地址。 返回值:成功:0失敗:非 0 錯誤碼04. 互斥鎖示例
示例代碼如下:
#include <stdio.h> #include <pthread.h> #include <unistd.h>pthread_mutex_t mutex; //互斥鎖// 打印機 void printer(char *str) {pthread_mutex_lock(&mutex); //上鎖while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n"); pthread_mutex_unlock(&mutex); //解鎖 }// 線程一 void *thread_fun_1(void *arg) {char *str = "hello";printer(str); //打印 }// 線程二 void *thread_fun_2(void *arg) {char *str = "world";printer(str); //打印 }int main(void) {pthread_t tid1, tid2;pthread_mutex_init(&mutex, NULL); //初始化互斥鎖// 創建 2 個線程pthread_create(&tid1, NULL, thread_fun_1, NULL);pthread_create(&tid2, NULL, thread_fun_2, NULL);// 等待線程結束,回收其資源pthread_join(tid1, NULL);pthread_join(tid2, NULL); pthread_mutex_destroy(&mutex); //銷毀互斥鎖return 0; }測試結果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out hello world deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$05. 總結
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Linux系统编程】互斥锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux系统编程】同步和互斥的概念
- 下一篇: 【Linux系统编程】POSIX无名信号