读者写者模型(读写锁)
在编写多线程时,有可能会出现有些公共区域的数据修改的机会比较少,但是读的机会反而很多,也就是说写者少,读者多。那么在读的过程中往往伴随着查找的操作,耗时较长,如果给这种代码加锁的话,会导致效率的降低,因此读写锁就是针对多读少写的情况。
当前锁状态 | 读锁请求 | 写锁请求 |
---|---|---|
无锁 | 可以 | 可以 |
读锁 | 可以 | 阻塞 |
写锁 | 阻塞 | 阻塞 |
这里默认是读锁优先的,因为读者非常的多,但是这样也就会导致写锁的饥饿问题。
读者写者模型和生产者消费者模型的区别?
读者写者模型和生产者消费者模型最大的区别就是生产者生产数据之后,消费者就会将数据消费掉,其他消费者则无法享受该数据。而读者写者模型中写者进行数据的写入时,所有的读者都可以享受该数据,直到写者再次写入。
读者写者模型中的三重关系?
写者和写者的关系:互斥
读者和读者的关系:共享
读者和写者的关系:互斥和同步(当写者进行数据写入时,读者不可以进行数据的读取,当读者进行数据的读取时,写者不可以进行数据的写入,同时读者必须等待写者把数据写完才可以进行数据的写入)
既然读读不互斥,为何还要加读锁?
答: 如果只是读,是不需要加锁的,加锁本身就有性能上的损耗
如果读可以不是最新数据,也不需要加锁
如果读必须是最新数据,必须加读写锁
读写锁相较于互斥锁的优点仅仅是允许读读的并发,除此之外并无其他。
读写锁相关函数
读写锁的初始化(pthread_rwlock_init)
功能: 初始化读写锁
#include<pthread.h> int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthred_rwlockattr_t *restrict attr);
参数说明:
rwlock: 是要进行初始化的读写锁
attr:是rwlock的属性,此参数一般不关注,可设为NULL
读写锁的销毁(pthread_rwlock_destroy)
功能: 销毁初始化的锁
#include<pthread.h> int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
参数说明:
rwlock: 是需要进行销毁的锁
加读锁(pthread_rdlock_lock)
pthread_rwlock_rdlock(pthread_rwlock_t