C語(yǔ)言多線程開(kāi)發(fā)中死鎖與讀寫(xiě)鎖問(wèn)題詳解
死鎖
有時(shí),一個(gè)線程需要同時(shí)訪問(wèn)兩個(gè)或更多不同的共享資源,而每個(gè)資源又都由不同的互斥量管理。當(dāng)超過(guò)一個(gè)線程加鎖同一組互斥量時(shí),就有可能發(fā)生死鎖;
兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中,因爭(zhēng)奪共享資源而造成的一種互相等待的現(xiàn)象,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去。此時(shí)稱(chēng)系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖。
死鎖的幾種場(chǎng)景:
- 忘記釋放鎖
- 重復(fù)加鎖(重復(fù)加相同的鎖)
- 多線程多鎖,搶占鎖資源

//多線程多鎖,搶占鎖資源
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 創(chuàng)建2個(gè)互斥量
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個(gè)子線程
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é)果:

讀寫(xiě)鎖
/*
讀寫(xiě)鎖的類(lèi)型 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個(gè)線程操作同一個(gè)全局變量。
3個(gè)線程不定時(shí)寫(xiě)這個(gè)全局變量,5個(gè)線程不定時(shí)的讀這個(gè)全局變量
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 創(chuàng)建一個(gè)共享數(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個(gè)寫(xiě)線程,5個(gè)讀線程
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);
}
// 設(shè)置線程分離
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é)果:
讀時(shí)共享,相比互斥鎖,提高效率。

到此這篇關(guān)于C語(yǔ)言多線程開(kāi)發(fā)中死鎖與讀寫(xiě)鎖問(wèn)題詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言死鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言創(chuàng)建動(dòng)態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下)
本篇文章主要介紹了C語(yǔ)言創(chuàng)建動(dòng)態(tài)dll和調(diào)用dll(visual studio 2013環(huán)境下),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-11-11
詳解C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配
內(nèi)存分配 (Memory Allocation) 是指為計(jì)算機(jī)程序或服務(wù)分配物理內(nèi)存空間或虛擬內(nèi)存空間的一個(gè)過(guò)程,本文主要介紹了C++的靜態(tài)內(nèi)存分配與動(dòng)態(tài)內(nèi)存分配,感興趣的同學(xué)可以參考閱讀2023-06-06
解析取模運(yùn)算% 和位與運(yùn)算& 之間的關(guān)系詳解
本篇文章是對(duì)取模運(yùn)算%和位與運(yùn)算&之間的關(guān)系進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++基于單鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++基于單鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
C++實(shí)現(xiàn)LeetCode(190.顛倒二進(jìn)制位)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(190.顛倒二進(jìn)制位),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
c/c++拷貝構(gòu)造函數(shù)和關(guān)鍵字explicit詳解
這篇文章主要介紹了c/c++拷貝構(gòu)造函數(shù)和關(guān)鍵字explicit的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
c語(yǔ)言根據(jù)用戶(hù)輸入的出生年份并計(jì)算出當(dāng)前年齡
這篇文章主要介紹了c語(yǔ)言根據(jù)用戶(hù)輸入的出生年份并計(jì)算出當(dāng)前年齡,需要的朋友可以參考下2023-03-03

