C語言多線程開發(fā)中死鎖與讀寫鎖問題詳解
死鎖
有時,一個線程需要同時訪問兩個或更多不同的共享資源,而每個資源又都由不同的互斥量管理。當超過一個線程加鎖同一組互斥量時,就有可能發(fā)生死鎖;
兩個或兩個以上的進程在執(zhí)行過程中,因爭奪共享資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去。此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖。
死鎖的幾種場景:
- 忘記釋放鎖
- 重復加鎖(重復加相同的鎖)
- 多線程多鎖,搶占鎖資源
//多線程多鎖,搶占鎖資源 #include <stdio.h> #include <pthread.h> #include <unistd.h> // 創(chuàng)建2個互斥量 pthread_mutex_t mutex1, mutex2; void * workA(void * arg) { pthread_mutex_lock(&mutex1); sleep(1); pthread_mutex_lock(&mutex2); printf("workA....\n"); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); return NULL; } void * workB(void * arg) { pthread_mutex_lock(&mutex2); sleep(1); pthread_mutex_lock(&mutex1); printf("workB....\n"); pthread_mutex_unlock(&mutex1); pthread_mutex_unlock(&mutex2); return NULL; } int main() { // 初始化互斥量 pthread_mutex_init(&mutex1, NULL); pthread_mutex_init(&mutex2, NULL); // 創(chuàng)建2個子線程 pthread_t tid1, tid2; pthread_create(&tid1, NULL, workA, NULL); pthread_create(&tid2, NULL, workB, NULL); // 回收子線程資源 pthread_join(tid1, NULL); pthread_join(tid2, NULL); // 釋放互斥量資源 pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); return 0; }
執(zhí)行結(jié)果:
讀寫鎖
/* 讀寫鎖的類型 pthread_rwlock_t int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); 案例:8個線程操作同一個全局變量。 3個線程不定時寫這個全局變量,5個線程不定時的讀這個全局變量 */ #include <stdio.h> #include <pthread.h> #include <unistd.h> // 創(chuàng)建一個共享數(shù)據(jù) int num = 1; // pthread_mutex_t mutex; pthread_rwlock_t rwlock; void * writeNum(void * arg) { while(1) { pthread_rwlock_wrlock(&rwlock); num++; printf("++write, tid : %ld, num : %d\n", pthread_self(), num); pthread_rwlock_unlock(&rwlock); usleep(100); } return NULL; } void * readNum(void * arg) { while(1) { pthread_rwlock_rdlock(&rwlock); printf("===read, tid : %ld, num : %d\n", pthread_self(), num); pthread_rwlock_unlock(&rwlock); usleep(100); } return NULL; } int main() { pthread_rwlock_init(&rwlock, NULL); // 創(chuàng)建3個寫線程,5個讀線程 pthread_t wtids[3], rtids[5]; for(int i = 0; i < 3; i++) { pthread_create(&wtids[i], NULL, writeNum, NULL); } for(int i = 0; i < 5; i++) { pthread_create(&rtids[i], NULL, readNum, NULL); } // 設置線程分離 for(int i = 0; i < 3; i++) { pthread_detach(wtids[i]); } for(int i = 0; i < 5; i++) { pthread_detach(rtids[i]); } pthread_exit(NULL); pthread_rwlock_destroy(&rwlock); return 0; }
執(zhí)行結(jié)果:
讀時共享,相比互斥鎖,提高效率。
到此這篇關于C語言多線程開發(fā)中死鎖與讀寫鎖問題詳解的文章就介紹到這了,更多相關C語言死鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言創(chuàng)建動態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下)
本篇文章主要介紹了C語言創(chuàng)建動態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下),非常具有實用價值,需要的朋友可以參考下2017-11-11詳解C++的靜態(tài)內(nèi)存分配與動態(tài)內(nèi)存分配
內(nèi)存分配 (Memory Allocation) 是指為計算機程序或服務分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個過程,本文主要介紹了C++的靜態(tài)內(nèi)存分配與動態(tài)內(nèi)存分配,感興趣的同學可以參考閱讀2023-06-06C++基于單鏈表實現(xiàn)學生成績管理系統(tǒng)
這篇文章主要為大家詳細介紹了C++基于單鏈表實現(xiàn)學生成績管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05C++實現(xiàn)LeetCode(190.顛倒二進制位)
這篇文章主要介紹了C++實現(xiàn)LeetCode(190.顛倒二進制位),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08c/c++拷貝構(gòu)造函數(shù)和關鍵字explicit詳解
這篇文章主要介紹了c/c++拷貝構(gòu)造函數(shù)和關鍵字explicit的相關知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08