Linux学习之系统编程篇:互斥锁(pthread_mutex_init / lock / trylock / unlock / destroy)
一、主要函數介紹
(1)定義鎖 :
pthread_mutex_t mutex; //互斥鎖 數據類pthread_mutex_t(2)初始化鎖:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr // 參數 1:定義的鎖;參數2: 互斥鎖屬性,通常傳 NULL);注:restrict 是一個修飾指針的關鍵字,對該函數的使用沒有影響,只是為了保證鎖的唯一性。
作用:指針 p 指向一塊內存,s = p ,因此通過 s 也可以訪問該內存,但是有了 restrict 修飾 p,s 就不能訪問該內存了。
(3)加鎖:
mutex 沒有被上鎖,當前線程會將鎖鎖上,如果 mutex 被上鎖,當前線程會阻塞,直至被解鎖后,解除阻塞。
int pthread_mutex_trylock(pthread_mutex_t *mutex); //嘗試加鎖mutex 沒有被上鎖,當前線程會將鎖鎖上,如果 mutex 被上鎖,直接返回,不阻塞。
用法:
(4)解鎖:
int pthread_mutex_unlock(pthread_mutex_t *mutex);(5)銷毀鎖:
int pthread_mutex_destroy(pthread_mutex_t *mutex);以上函數的返回值都是成功返回 0, 失敗返回錯誤號。
二、上述函數引用實例的加鎖修改
#include <stdio.h> #include <unistd.h> #include <string.h> #include <pthread.h> #define MAX 10000 // 定義互斥鎖 pthread_mutex_t mutex; //定義全局變量 int num = 0; void *func_a(void *arg) {for(int i = 0; i < MAX; i++){// 訪問全局變量前加鎖pthread_mutex_lock(&mutex);// 阻塞,直至鎖處于解鎖狀態,該子線程訪問全局變量int cur = num;cur++;num = cur;printf("Thread A ,id = %lu, num = %d\n",pthread_self(), num);// 解鎖pthread_mutex_unlock(&mutex);usleep(10);}return NULL; } void *func_b(void *arg) {for(int i = 0; i < MAX; i++){pthread_mutex_lock(&mutex); int cur = num;cur++;num = cur;printf("Thread B ,id = %lu, num = %d\n",pthread_self(), num);pthread_mutex_unlock(&mutex); usleep(10);}return NULL; } int main() {pthread_t p1, p2;// 初始化互斥鎖pthread_mutex_init(&mutex, NULL);// 創建兩個子線程pthread_create(&p1, NULL, func_a, NULL);pthread_create(&p2, NULL, func_b, NULL);// 阻塞回收資源pthread_join(p1, NULL);pthread_join(p2, NULL);// 銷毀互斥鎖pthread_mutex_destroy(&mutex);return 0; }最后 num = 20000
三、使用互斥鎖的注意問題
(1)pthread_mutex_ lock 和 pthread_mutex_ unlock 之間稱為臨界區,臨界區越小越好。
(2)使用 pthread_mutex_trylock 要作返回值判斷。
(3)作線程同步,操作共享數據的所有線程都要上鎖,而且上同一把鎖。
說明:lock 和 unlock 之間其實模擬了一個“原子操作”,這也是不會產生數據混亂的根本原因。原子操作就是該操作不可分隔,或者說,該操作執行過程中,不會丟失 CPU。
注意:lock 和 unlock 會丟失 CUP ,但是由于上鎖,即使其他線程搶到 CPU,也會因為阻塞而丟棄 CPU,也就是說,只有原線程能再次搶到 CPU,因此該執行過程效果跟原子操作相同。
總結
以上是生活随笔為你收集整理的Linux学习之系统编程篇:互斥锁(pthread_mutex_init / lock / trylock / unlock / destroy)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习之系统编程篇:线程同步的引
- 下一篇: Linux学习之系统编程篇:死锁的情形及