目录
读写锁
一把锁,并不是读锁和写锁
称之为读写锁,因为他既可以锁定读操作,也可以锁定写操作
pthread_rwlock_t rwlock;
锁中记录了
- 锁的状态 打开关闭
- 锁定的操作 锁读 锁写
- 哪个线程持有钥匙
使用方式和互斥锁相同:
- 找共享资源
- 确定临界区
- 临界区加锁,解锁
特点
- 读锁锁定了临界区,线程对临界区的访问是并行的,读锁共享
- 写锁锁定了临界区,线程对临界区的访问是串行的,写锁独占
- 多个请求读写锁,写锁优先
读操作多时,可以选用读写锁,效率较高
函数
初始化和析构
#include<pthread_h>
pthread_rwlock_t rwlock;
//初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);
//释放资源
pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
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);
如果读写锁是没上锁的,那么加锁成功。如果读写锁已经锁定,那么阻塞操作
同样有try加锁的命令
// 这个函数可以有效的避免死锁
// 如果加写锁失败, 不会阻塞当前线程, 直接返回错误号
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
解锁
//读写锁都可以解锁
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);
读写锁使用
写一个程序,有5个线程对全局变量进行读操作,3个线程进行写操作
#include <pthread.h>
#include <iostream>
#include <bits/stdc++.h>
#include <unistd.h>
#define MAX 50
// 全局变量
int number;
pthread_rwlock_t rwlock1;
using namespace std;
void *read_num(void *arg)
{
for (int i = 0; i < MAX; i++)
{
pthread_rwlock_rdlock(&rwlock1);
cout << "thread read,id= " << pthread_self() << " number= " << number << endl;
pthread_rwlock_unlock(&rwlock1);
usleep(rand() % 5);
}
return NULL;
}
void *write_num(void *arg)
{
for (int i = 0; i < MAX; i++)
{
pthread_rwlock_wrlock(&rwlock1);
int cur=number;
cur++;
number=cur;
cout << "thread write,id= " << pthread_self() << " number= " << number << endl;
pthread_rwlock_unlock(&rwlock1);
};
return NULL;
}
int main()
{
pthread_t p1[5], p2[3];
// 初始化锁
pthread_rwlock_init(&rwlock1, NULL);
// 5个读线程,3个写线程
for (int i = 0; i < 5; i++)
{
pthread_create(&p1[i], NULL, read_num, NULL);
}
for (int i = 0; i < 3; i++)
{
pthread_create(&p1[i], NULL, write_num, NULL);
}
// 阻塞后资源回收
for (int i = 0; i < 5; i++)
{
pthread_join(p1[i], NULL);
}
for (int i = 0; i < 3; i++)
{
pthread_join(p2[i], NULL);
}
// 释放锁
pthread_rwlock_destroy(&rwlock1);
return 0;
}
实现结果