ltp测试套件-pthread_rwlock_rdlock_2-1分析记录

本文分析了pthread_rwlock_rdlock_2-1测试用例失败的原因,探讨了读写锁的工作原理。在默认情况下,多个读者可以并发读取,但在有写者竞争时,读者应被阻塞。为使测试用例通过,需要在初始化读写锁时设置写者优先属性。
摘要由CSDN通过智能技术生成

测试pthread_rwlock_rdlock_2-1.c用例失败。log如下:

[83#yuchen@ubuntu ltp]# gcc 2-1.c -o 21 -pthread
[84#yuchen@ubuntu ltp]# ./21
main: has priority: 3
main: attempt read lock
main: acquired read lock
main: create wr_thread, with priority: 2
wr_thread: attempt write lock
main: create rd_thread, with priority: 1
rd_thread: attempt read lock
rd_thread: acquired read lock
rd_thread: unlock read lock
Test FAILED: rd_thread did not block on read lock, when a reader owns the lock, and a higher priority writer is waiting for the lock
[85#yuchen@ubuntu ltp]#

 这个测试用例的流程:

Steps:
 * We have three threads, main(also a reader), writer, reader
 *
 * 1.  Main thread set its shcedule policy as "SCHED_FIFO", with highest priority
 *     the three: sched_get_priority_min()+2.
 * 2.  Main thread read lock 'rwlock'
 * 3.  Create a writer thread, with schedule policy as "SCHED_FIFO", and priority
 *     using sched_get_priority_min()+1.
 * 4.  The thread write lock 'rwlock', should block.
 * 5.  Main thread create a reader thread, with schedule policy as "SCHED_FIFO", and
 *     priority sched_get_priority_min()
 * 6.  Reader thread read lock 'rwlock', should block, since there is a higher priority
 *     writer blocked on 'rwlock'
 * 7.  Main thread release the 'rwlock', the writer should get the lock first
 */

用例失败的原因:

rwlock是读写锁,读者是可以递归调用的,因为多个读者不存在竞争问题,如果写者先拿到了锁,则后面来的读者必须阻塞。读和写之间必然会造成竞争,但是读和读之间没有竞争。读写锁的实现比较复杂,基于futex实现(用户态和内核态混合同步机制)。在glibc库有很多分支判断,如果对futex机制不了解的话,是比较难理解的。针对这个用例,简单说下流程:

默认情况下,如果没有写者持有锁,并且锁的属性设置了读优先(默认情况下rwlock就是读优先的),那么读者可以重复占用锁(读和读没有竞争)。代码见nptl/pthread_rwlock_rdlock.c,注意140行。那么在该测试用例中有2个读者,读者1先拿到了锁,读者2在去拿锁,是不会被阻塞的,因为写者并没有持有锁。持有锁的是一个读者(main主程序)。

但是测试用例期望,在有高优先级写者竞争锁的时候,读者要阻塞。从c库代码上看,要想让读者阻塞,必须设置rwlock写者优先属性,也就是让pthread_rwlock_rdlock.c的140行的条件判断为假。从而让代码走到slowfast,在pthread_rwlock_rdlock_slow函数中会挂起当前线程,等待其他任务unlock时才有可能被唤醒。

119 __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
120 {
121   int result = 0;
122   bool wake = false;
123   int futex_shared =
124       rwlock->__data.__shared == LLL_PRI
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值