linux 线程 读写锁
读写锁:🔴🟠🟡🟢🔵🟣🟤⚫⚪
当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是由于互斥锁的排他性,所有其他线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会产生问题。
在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用。为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现。
读写锁的特点:
🟢 如果有其他线程读数据,则允许其他线程执行读操作,但不允许写操作。
🟢 如果有其他线程写数据,则其他线程都不允许读、写操作
🟢 写是独占的,写的优先级高。
错误案例:可能读取9515 写入9514,未写入先读取(错误)。
1 /* 2 读写锁的类型 pthread_rwlock_t 3 int pthread_rwlock_init(pthread_rwlock_t * restrict rwlock, const pthread_rwlockattr_t * restrict attr); 4 int pthread_rwlock_destroy(pthread_rwlock_t * rwlock); 5 int pthread_rwlock_relock(pthread_rwlock_t * rwlock); 6 int pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock); 7 int pthread_rwlock_wrlock(pthread_rwlock_t * rwlock); 8 int pthread_rwlock_trywrlock(pthread_rwlock_t * rwlock); 9 int pthread_rwlock_unlock(pthread_rwlock_t * rwlock); 10 //案例:8个线程 操作同全局变量 11 3个线程不定时写这个全局变量 12 其余5个线程不定时读这个全局变量 13 */ 14 #include <stdio.h> 15 #include <unistd.h> 16 #include <pthread.h> 17 #include <string.h> 18 //创建一个共享数据 19 int num = 1; 20 void * writeNum(void * arg) 21 { 22 while(1) 23 { 24 num++; 25 printf("++write, tid : %ld,num: %d\n",pthread_self(),num); 26 usleep(100); 27 } 28 return NULL; 29 } 30 void * readNum(void * arg) 31 { 32 while(1) 33 { 34 printf("==read , tid : %ld, num: %d\n",pthread_self(),num); 35 usleep(100); 36 } 37 return NULL; 38 } 39 int main() 40 { 41 //创建3个写线程,5个读线程 42 pthread_t wtids[3],rtids[5]; 43 for(int i = 0; i < 3;i++) 44 { 45 pthread_create(&wtids[i], NULL, writeNum, NULL); 46 } 47 for(int i = 0; i < 5;i++) 48 { 49 pthread_create(&rtids[i], NULL, readNum, NULL); 50 } 51 //设置线程分离 52 for(int i = 0; i < 3;i++) 53 { 54 pthread_detach(wtids[i]); 55 } 56 for(int i = 0; i < 5;i++) 57 { 58 pthread_detach(rtids[i]); 59 } 60 pthread_exit(NULL);//主线程退出,子线程继续运行 61 return 0; 62 }
使用互斥锁可以解决但效率低:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <pthread.h> 4 #include <string.h> 5 //创建一个共享数据 6 int num = 1; 7 pthread_mutex_t mutex; 8 void * writeNum(void * arg) 9 { 10 while(1) 11 { 12 pthread_mutex_lock(&mutex); 13 num++; 14 printf("++write, tid : %ld,num: %d\n",pthread_self(),num); 15 pthread_mutex_unlock(&mutex); 16 usleep(100); 17 } 18 return NULL; 19 } 20 void * readNum(void * arg) 21 { 22 while(1) 23 { 24 pthread_mutex_lock(&mutex); 25 printf("==read , tid : %ld, num: %d\n",pthread_self(),num); 26 pthread_mutex_unlock(&mutex); 27 usleep(100); 28 } 29 return NULL; 30 } 31 int main() 32 { 33 pthread_mutex_init(&mutex, NULL); 34 //创建3个写线程,5个读线程 35 pthread_t wtids[3],rtids[5]; 36 for(int i = 0; i < 3;i++) 37 { 38 pthread_create(&wtids[i], NULL, writeNum, NULL); 39 } 40 for(int i = 0; i < 5;i++) 41 { 42 pthread_create(&rtids[i], NULL, readNum, NULL); 43 } 44 //设置线程分离 45 for(int i = 0; i < 3;i++) 46 { 47 pthread_detach(wtids[i]); 48 } 49 for(int i = 0; i < 5;i++) 50 { 51 pthread_detach(rtids[i]); 52 } 53 pthread_exit(NULL);//主线程退出,子线程继续运行 54 55 pthread_mutex_destroy(&mutex); 56 return 0; 57 }
读写锁:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <pthread.h> 4 #include <string.h> 5 //创建一个共享数据 6 int num = 1; 7 pthread_rwlock_t rwlock; 8 void * writeNum(void * arg) 9 { 10 while(1) 11 { 12 pthread_rwlock_wrlock(&rwlock); 13 num++; 14 printf("++write, tid : %ld,num: %d\n",pthread_self(),num); 15 pthread_rwlock_unlock(&rwlock); 16 usleep(100); 17 } 18 return NULL; 19 } 20 void * readNum(void * arg) 21 { 22 while(1) 23 { 24 pthread_rwlock_rdlock(&rwlock); 25 printf("==read , tid : %ld, num: %d\n",pthread_self(),num); 26 pthread_rwlock_unlock(&rwlock); 27 usleep(100); 28 } 29 return NULL; 30 } 31 int main() 32 { 33 pthread_rwlock_init(&rwlock,NULL); 34 //创建3个写线程,5个读线程 35 pthread_t wtids[3],rtids[5]; 36 for(int i = 0; i < 3;i++) 37 { 38 pthread_create(&wtids[i], NULL, writeNum, NULL); 39 } 40 for(int i = 0; i < 5;i++) 41 { 42 pthread_create(&rtids[i], NULL, readNum, NULL); 43 } 44 //设置线程分离 45 for(int i = 0; i < 3;i++) 46 { 47 pthread_detach(wtids[i]); 48 } 49 for(int i = 0; i < 5;i++) 50 { 51 pthread_detach(rtids[i]); 52 } 53 pthread_exit(NULL);//主线程退出,子线程继续运行 54 55 pthread_rwlock_destroy(&rwlock); 56 return 0; 57 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)