目次
(1) 読み取り/書き込みロックの初期化/破棄 (pthread_rwlock_destroy、pthread_rwlock_init)
(2) ブロッキング追加リード/ライトロック/ノンブロッキング追加リード/ライトロック/アンロック
1. 相互排他ロックのデメリット
プログラム リソースの大部分が読み取り操作である場合、ミューテックスによって複数のスレッドがブロックされ、リソースの取得中に待機するため、プログラムの効率が低下します。
2. 読み書きロックのメリット
(1) 読み取りロック: 複数のスレッドが同時にリソースを読み取ることができ、同時に複数の読み取りロックを追加できます
(2) 書き込みロック: 同時に 1 つのスレッドのみがリソースを読み取ることができ、他のスレッドはロック リソースを保持できません。
3. 読み書きロックの操作手順
(1) 読み書きロックの初期化 pthread_rwlock_init()
(2) 読み取りロック/書き込みロックを追加 pthread_rwlock_rdlock / pthread_rwlock_wrlock
(3) 共有リソースが使用されなくなったら、pthread_rwlock_unlock() のロックを解除します
(4) pthread_rwlock_destroy() は、読み取り/書き込みロックが不要な場合に破棄できます
4、API
(1) 読み取り/書き込みロックの初期化/破棄 (pthread_rwlock_destroy、pthread_rwlock_init)
(2) ブロッキング追加リード/ライトロック/ノンブロッキング追加リード/ライトロック/アンロック
5. コード
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
char * msg = NULL ;
pthread_rwlock_t rwlock ;
void * FUNC(void * arg )
{
int num = (int ) arg ;
// printf("num:%d\n" , num);
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf("我是%d号线程,我看到的消息是:%s\n" , (int)arg , msg) ;
pthread_rwlock_unlock(&rwlock);
sleep(1);//刚好所有的读锁都睡觉了,就上写锁
}
}
int main(int argc, char const *argv[])
{
msg = calloc(128,1);
// 初始化锁资源
pthread_rwlock_init(&rwlock, NULL );
// 创建多个线程
pthread_t thread1 ;
pthread_t thread2 ;
pthread_t thread3 ;
pthread_t thread4 ;
pthread_t thread5 ;
pthread_t thread6 ;
pthread_create(&thread1, NULL, FUNC , (void *)1 );
pthread_create(&thread2, NULL, FUNC , (void *)2 );
pthread_create(&thread3, NULL, FUNC , (void *)3 );
pthread_create(&thread4, NULL, FUNC , (void *)4 );
pthread_create(&thread5, NULL, FUNC , (void *)5 );
pthread_create(&thread6, NULL, FUNC , (void *)6 );
while (1)
{
// 申请上写锁 --> 写锁在同一时间内只允许上一个
printf("等待上写锁.....\n");
pthread_rwlock_wrlock(&rwlock);
printf("成功获得写锁.....\n");
fgets(msg , 128 , stdin) ;
pthread_rwlock_unlock(&rwlock);
printf("解除写锁状态.....\n");
sleep(5);
}
return 0;
}
6. 注意事項
読み込みロック、書き込みロックに関わらず、ロック時には現在の共有リソースの状態を判断する必要があります。
読み取りロック: スレッドが情報を読み取るとき、最初に書き込みロックが存在するかどうかを確認し、存在する場合は待機し、存在しない場合は読み取りロックを追加します
書き込みロック: スレッドが情報を書き込むときに、誰かがそれを読み取ったかどうかを確認し、読み取った場合は待機し、そうでない場合は書き込みロックを追加します