Linux多线程的同步------读写锁
前面介紹過Linux多線程同步的另外兩個方法------互斥鎖和信號量
Linux多線程的同步-----信號量和互斥鎖_神廚小福貴!的博客-CSDN博客
下面來看一下讀寫鎖:
? ? ? ? 讀寫鎖和互斥鎖都帶有一個鎖,那么他們有什么區別呢?
| 讀寫鎖 | 互斥鎖 | 
| 多個讀操作可以同時進行 | 一次只有一個線程擁有互斥鎖,其他線程只有等待 | 
| 寫操作之間必須互斥 | |
| 讀寫操作之間也是互斥的,且寫操作的應優先于讀操作(寫操作執行的時候,其他函數都在阻塞) | 
上面說到了讀寫鎖和互斥鎖的區別,相信大家對讀寫鎖已經有了一定的理解,下面來看讀寫鎖所用到的函數以及頭文件:
 頭文件:#include <pthread.h>?
讀寫鎖初始化函數:
int pthread_rwlock_init(pthread_rwlock_t *rwlock, pthread_rwlockattr_t *attr);?
第一個參數是讀寫鎖指針,第二個參數是讀寫鎖的屬性的指針(一般置為NULL)----下面附上官方手冊
?讀鎖:int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);?
寫鎖:int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);?
解鎖:int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);?
銷毀鎖:int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);?
函數里面的參數都是所創建的讀寫鎖的指針
下面來看一個代碼示例:下面代碼是沒有加讀寫鎖🔓的代碼
#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>
#include <string.h>
#include <pthread.h>pthread_rwlock_t rwlock;//讀寫鎖的創建void * read_fun1(void * arg)   //讀子線程的函數
{while(1){printf("read1 start \n");sleep(1);printf("read2 end \n");}
} 
void * read_fun2(void * arg)
{while(1){printf("read2 start \n");sleep(1);printf("read2 end \n");}
}void * write_fun(void * arg)
{while(1){printf("write start \n");sleep(1);printf("write end  \n");}
}int main()
{pthread_rwlock_init(&rwlock,NULL);pthread_t idr1,idr2; //創建兩個讀的線程pthread_t idw;  //創建一個寫的線程pthread_create(&idr1,NULL,read_fun1,NULL);pthread_create(&idr2,NULL,read_fun2,NULL);pthread_create(&idw,NULL,write_fun,NULL);pthread_join(idr1,NULL);pthread_join(idr2,NULL);pthread_join(idw,NULL);pthread_rwlock_destroy(&rwlock);exit(0);
}
~      
上面代碼沒有加讀寫鎖,我們來運行結果:
?運行結果可看出,在讀操作進行的同時,寫操作也在進行著,那么我們再來看一下加了讀寫鎖之后的運行結果
來看加了讀寫鎖之后的代碼:
#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>
#include <string.h>
#include <pthread.h>pthread_rwlock_t rwlock;//讀寫鎖的創建void * read_fun1(void * arg)   //讀子線程的函數
{while(1){pthread_rwlock_rdlock(&rwlock);   //對讀操作枷鎖printf("read1 start \n");sleep(1);printf("read2 end \n");pthread_rwlock_unlock(&rwlock);   //讀完進行解鎖}
} 
void * read_fun2(void * arg)
{while(1){pthread_rwlock_rdlock(&rwlock);   //對讀操作枷鎖printf("read2 start \n");sleep(1);printf("read2 end \n");pthread_rwlock_unlock(&rwlock);   //讀完進行解鎖}
}void * write_fun(void * arg)
{while(1){pthread_rwlock_wrlock(&rwlock);   //對寫操作枷鎖printf("write start \n");sleep(1);printf("write end  \n");pthread_rwlock_unlock(&rwlock);   //寫完進行解鎖}
}int main()
{pthread_rwlock_init(&rwlock,NULL);pthread_t idr1,idr2; //創建兩個讀的線程pthread_t idw;  //創建一個寫的線程pthread_create(&idr1,NULL,read_fun1,NULL);pthread_create(&idr2,NULL,read_fun2,NULL);pthread_create(&idw,NULL,write_fun,NULL);pthread_join(idr1,NULL);pthread_join(idr2,NULL);pthread_join(idw,NULL);pthread_rwlock_destroy(&rwlock);exit(0);
}
~      
加了鎖之后再來運行? ?看結果:
?看了結果發現,誒,怎么還是不對啊,怎么沒有寫操作呢?
在我上面的代碼中,是讀操作的線程創建函數先于寫操作的線程創建函數,然后剛開始就是讀拿鎖,又因為讀操作是可以同時拿鎖的,所以兩個讀操作同時拿鎖,中間可能會有間隔 ,但是這個間隔時間之中是另外一個讀操作在拿鎖,所以寫操作就一直拿不到鎖,但是你只要給每次解鎖之后加個睡眠一秒鐘的函數,就會改善這種情況
#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>
#include <string.h>
#include <pthread.h>pthread_rwlock_t rwlock;//讀寫鎖的創建void * read_fun1(void * arg)   //讀子線程的函數
{while(1){pthread_rwlock_rdlock(&rwlock);   //對讀操作枷鎖printf("read1 start \n");sleep(1);printf("read2 end \n");pthread_rwlock_unlock(&rwlock);   //讀完進行解鎖sleep(1);}
} 
void * read_fun2(void * arg)
{while(1){pthread_rwlock_rdlock(&rwlock);   //對讀操作枷鎖printf("read2 start \n");sleep(1);printf("read2 end \n");pthread_rwlock_unlock(&rwlock);   //讀完進行解鎖sleep(1);}
}void * write_fun(void * arg)
{while(1){pthread_rwlock_wrlock(&rwlock);   //對寫操作枷鎖printf("write start \n");sleep(1);printf("write end  \n");pthread_rwlock_unlock(&rwlock);   //寫完進行解鎖sleep(1);}
}int main()
{pthread_rwlock_init(&rwlock,NULL);pthread_t idr1,idr2; //創建兩個讀的線程pthread_t idw;  //創建一個寫的線程pthread_create(&idr1,NULL,read_fun1,NULL);pthread_create(&idr2,NULL,read_fun2,NULL);pthread_create(&idw,NULL,write_fun,NULL);pthread_join(idr1,NULL);pthread_join(idr2,NULL);pthread_join(idw,NULL);pthread_rwlock_destroy(&rwlock);exit(0);
}
 
加上睡眠函數之后的運行結果:
?就可以了,這是因為在讀完數據之后,間隔那一秒鐘,讀操作空閑不拿鎖的時候,那個寫操作就可以拿到鎖子,但是這玩意說到底的優先級是什么,別人做過實驗,結果是寫操作優先:
讀寫鎖的一個奇怪表現 - 付哲 - 博客園
總結
以上是生活随笔為你收集整理的Linux多线程的同步------读写锁的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 线程安全之strtok()函数
 - 下一篇: 天道无极的神化奥义,神天道提全数值是几回