日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux线程同步(3)-读写锁

發布時間:2025/3/21 linux 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux线程同步(3)-读写锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.概述 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

讀寫鎖與互斥量的功能類似,對臨界區的共享資源進行保護!互斥量一次只讓一個線程進入臨界區,讀寫鎖比它有更高的并行性。讀寫鎖有以下特點:

1.如果一個線程用讀鎖鎖定了臨界區,那么其他線程也可以用讀鎖來進入臨界區,這樣就可以多個線程并行操作。但這個時候,如果再進行寫鎖加鎖就會發生阻塞,寫鎖請求阻塞后,后面如果繼續有讀鎖來請求,這些后來的讀鎖都會被阻塞!這樣避免了讀鎖長期占用資源,防止寫鎖饑餓

2.如果一個線程用寫鎖鎖住了臨界區,那么其他線程不管是讀鎖還是寫鎖都會發生阻塞!

二.函數接口 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

1.創建讀寫鎖

1.1:宏常量初始化

1 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

1.2:函數初始化

1 #include <pthread.h> 2 3 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

rwlock:讀寫鎖的pthread_rwlock_t結構指針

attr:讀寫鎖的屬性結構指針。不需要別的屬性默認為NULL。

2.讀寫鎖加鎖與解鎖

1 #include <pthread.h> 2 3 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); 4 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); 5 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

rwlock:創建的讀寫鎖指針

3.其他類型的加鎖

1 #include <pthread.h> 2 #include <time.h> 3 4 5 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); 6 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); 7 8 int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout); 9 int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout);

try類函數加鎖:如果獲取不到鎖,會立即返回錯誤EBUSY

timed類函數加鎖:如果規定的時間內獲取不到鎖,會返回ETIMEDOUT錯誤!

4.銷毀讀寫鎖

1 #include <pthread.h> 2 3 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

三.簡單的例子 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

創建4個線程,2個線程讀鎖,2個線程寫鎖,觀察4個線程進入臨界區的順序

1 /** 2 * @file pthread_rwlock.c 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <pthread.h> 10 11 /* 初始化讀寫鎖 */ 12 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; 13 /* 全局資源 */ 14 int global_num = 10; 15 16 void err_exit(const char *err_msg) 17 { 18 printf("error:%s\n", err_msg); 19 exit(1); 20 } 21 22 /* 讀鎖線程函數 */ 23 void *thread_read_lock(void *arg) 24 { 25 char *pthr_name = (char *)arg; 26 27 while (1) 28 { 29 /* 讀加鎖 */ 30 pthread_rwlock_rdlock(&rwlock); 31 32 printf("線程%s進入臨界區,global_num = %d\n", pthr_name, global_num); 33 sleep(1); 34 printf("線程%s離開臨界區...\n", pthr_name); 35 36 /* 讀解鎖 */ 37 pthread_rwlock_unlock(&rwlock); 38 39 sleep(1); 40 } 41 42 return NULL; 43 } 44 45 /* 寫鎖線程函數 */ 46 void *thread_write_lock(void *arg) 47 { 48 char *pthr_name = (char *)arg; 49 50 while (1) 51 { 52 /* 寫加鎖 */ 53 pthread_rwlock_wrlock(&rwlock); 54 55 /* 寫操作 */ 56 global_num++; 57 printf("線程%s進入臨界區,global_num = %d\n", pthr_name, global_num); 58 sleep(1); 59 printf("線程%s離開臨界區...\n", pthr_name); 60 61 /* 寫解鎖 */ 62 pthread_rwlock_unlock(&rwlock); 63 64 sleep(2); 65 } 66 67 return NULL; 68 } 69 70 int main(void) 71 { 72 pthread_t tid_read_1, tid_read_2, tid_write_1, tid_write_2; 73 74 /* 創建4個線程,2個讀,2個寫 */ 75 if (pthread_create(&tid_read_1, NULL, thread_read_lock, "read_1") != 0) 76 err_exit("create tid_read_1"); 77 78 if (pthread_create(&tid_read_2, NULL, thread_read_lock, "read_2") != 0) 79 err_exit("create tid_read_2"); 80 81 if (pthread_create(&tid_write_1, NULL, thread_write_lock, "write_1") != 0) 82 err_exit("create tid_write_1"); 83 84 if (pthread_create(&tid_write_2, NULL, thread_write_lock, "write_2") != 0) 85 err_exit("create tid_write_2"); 86 87 /* 隨便等待一個線程,防止main結束 */ 88 if (pthread_join(tid_read_1, NULL) != 0) 89 err_exit("pthread_join()"); 90 91 return 0; 92 }

2個線程函數的臨界區里面都sleep(1),測試給足夠的時間看其他線程能不能進來。64行,寫鎖函數里面,sleep(2),因為寫鎖請求會阻塞后面的讀鎖,2個寫鎖一起請求會讓讀鎖饑餓,所以比39行的sleep(1)多一秒!

編譯運行:

可以看到,讀鎖可以一起進入臨界區,而寫鎖在臨界區里面等1秒都不會有其他線程能進來!!!

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的linux线程同步(3)-读写锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。