linux线程同步机制-读写锁
问题描述:
在对临界资源的访问中,更多的是读操作,而写操作较少,只有互斥量机制可能会影响效率
期望对临界资源的访问控制粒度更精细,任一时刻 允许多个线程对临界资源进行读操作,但只允许一个线程对临界资源进行写操作。
互斥 关系:
读操作 - 写操作互斥
写操作 - 写操作互斥
读操作 - 读操作不互斥
同步关系:
缓冲区不满,才允许写操作;缓冲区不空,才允许读操作
在保证互斥的基础上,linux提供了对临界资源访问控制粒度更细的读写锁机制
读写锁机制可以实现如下访问控制规则:
1)如果有线程对互斥资源进行读操作,则允许其他线程执行读操作,但不允许任何线程进行写操作
2)如果有线程对互斥资源进行写操作,则不允许任何线程进行读操作或写操作
读写锁操作(与互斥量操作类似)
1)定义读写锁变量
2)初始化读写锁变量
3)访问临界资源(读操作或写操作)前对读写锁加锁
4)访问临界资源后对读写锁解锁
5)销毁读写锁变量
读写锁的加锁操作在互斥量加锁的基础上扩展,具有加读锁和加写锁两种操作:
1)如果有线程已经成功对读写锁加读锁,其他线程可以继续对该线程加读锁,但不能加写锁(加写锁的线程可能会被阻塞)
2)如果有线程已经成功对读写锁加写锁,其他线程不能对该线程加读锁或者加写锁(可能导致调用线程阻塞)

1. 定义读写锁变量
pthread_rwlock_t rwlock;
2. 初始化读写锁
int pthread_rwlock_init( pthread_rwlock_t *__restrict __rwlock, __const pthread_rwlockattr_t *__restrict __attr );
3. 销毁读写锁
int pthread_rwlock_destroy( pthread_rwlock_t *__rwlock );
成功返回0,失败返回错误码
4. 加读锁
1)阻塞加读锁
int pthread_rwlock_rdlock( pthread_rwlock_t *__rwlock );
当有线程成功加写锁,将会阻塞调用该函数的线程,直到其他线程释放写锁;
当有线程成功加读锁,则该调用api成功执行,不会阻塞
2)非阻塞加读锁
int pthread_rwlock_tryrdlock( pthread_rwlock_t *__rwlock );
无论其他线程对读写锁加写锁,该函数都会立刻返回,可以通过返回值可以获知加读锁是否成功
3)限时等待加读锁
int pthread_rwlock_timerdlock( pthread_rwlock_t *__restrict __rwlock, __const struct timespec *__restrict __abstime );
可以指定等待时间,在等待时间之内,如果有其他线程对读写锁加写锁,调用线程将阻塞等待,直到等待时间超时。
如果等待时间之内,可以完成加锁操作,则立即进行加锁;如果不能加锁,那么会立刻返回错误
5. 加写锁
1)阻塞加写锁
int pthread_rwlock_wrock( pthread_rwlock_t *__rwlock );
2)非阻塞加写锁
int pthread_rwlock_trywrlock( pthread_rwlock_t *__rwlock );
3)限时等待加写锁
int pthread_rwlock_timewrlock( pthread_rwlock_t *__restrict __rwlock, __const struct timespec *__restrict __abstime );
6. 解锁
int pthread_rwlock_unlock( pthread_rwlock_t *__rwlock )
如何确定是为读锁还是为写锁解锁?
加锁(读/写锁)与解锁配对出现,为代码中距离最近的加锁操作解锁
浙公网安备 33010602011771号