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

测试用例地址:

https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_rwlock_unlock/3-1.c

测试用用例运行error log:

conformance/interfaces/pthread_rwlock_rdlock/pthread_rwlock_rdlock_2-1: execution: FAILED: Output: 
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

通过走查glibc库源码 和kernel的futex源码。在内核中添加了一些调试信息来观察futex在锁竞争时,分析唤醒任务的流程。

/tmp/ltp/conformance/interfaces/pthread_rwlock_unlock # ./pthread_rwlock_unlock_3-1.run-test
==========================main    268,===============================
==========================writer1 269,===============================
==========================reader1 270,===============================
==========================writer2 271,===============================
main: write lock             --主程序占有锁
main: create writer1, with priority: 3
writer1: attempt write lock
[futex_wait_in][2682]:current->comm=pthread_rwlock_,pid=269,hb=0x7b770b00   --writer1进入futex_wait等待unlock
main: create reader, with priority: 3
reader: attempt read lock
[futex_wait_in][2682]:current->comm=pthread_rwlock_,pid=270,hb=0x7b775880  --reader1进入futex_wait等待unlock 哈希桶不同
main: create writer2, with priority: 1
writer2: attempt write lock
[futex_wait_in][2682]:current->comm=pthread_rwlock_,pid=271,hb=0x7b770b00  --writer2进入futex_wait等待unlock 哈希桶和writer1相同
main: release write lock    --主程序释放锁
[futex_wake][1560]:current->comm=pthread_rwlock_,pid=268,hb=0x7b770b00
[mark_wake_futex][1569]:task->comm=pthread_rwlock_,pid=269,this->bitset=-1,bitset=-1
[mark_wake_futex][1575]:this->comm=pthread_rwlock_,pid=269,this->bitset=-1,bitset=-1
[futex_wait_out][2686]:current->comm=pthread_rwlock_,pid=269,hb=0x7b770b00  --writer1(269)拿到了锁
writer1: acquired write lock
[futex_wait_in][2682]:current->comm=pthread_rwlock_,pid=268,hb=0x7b7747c0  --主程序调用了pthread_join,等待writer1(269)退出。
[futex_wake][1560]:current->comm=pthread_rwlock_,pid=269,hb=0x7b770b00     --writer1(269)开始释放锁
writer1: unlock write lock
[mark_wake_futex][1569]:task->comm=pthread_rwlock_,pid=271,this->bitset=-1,bitset=-1
[mark_wake_futex][1575]:this->comm=pthread_rwlock_,pid=271,this->bitset=-1,bitset=-1  --writer(269)唤醒了writer2
[futex_wait_out][2686]:current->comm=pthread_rwlock_,pid=271,hb=0x7b770b00   --writer2拿到了锁。
writer2: acquired writer lock
[futex_wake][1560]:current->comm=pthread_rwlock_,pid=269,hb=0x7b7747c0     --write1线程退出,唤醒了主程序。
[mark_wake_futex][1569]:task->comm=pthread_rwlock_,pid=268,this->bitset=-1,bitset=-1
[mark_wake_futex][1575]:this->comm=pthread_rwlock_,pid=268,this->bitset=-1,bitset=-1
[futex_wait_out][2686]:current->comm=pthread_rwlock_,pid=268,hb=0x7b7747c0   --主程序继续运行。
Test failed: reader did not get the lock when writer1 release the lock  --由于测试用例要求高优先级的读者获取锁,导致失败。
[futex_wait_out][2686]:current->comm=pthread_rwlock_,pid=270,hb=0x7b775880
/tmp/ltp/conformance/interfaces/pthread_rwlock_unlock #
/tmp/ltp/conformance/interfaces/pthread_rwlock_unlock #


初步分析结论:
    pthread各种锁的原理,是采用了用户态与内核态混合同步方式,也就是内核futex机制,rwlock锁和普通的锁还不太一样,rwlock包含了reader,writer成员,对应内核态,读者和写者挂在了不同的等待队列上。
当多个进程在一把锁上发生竞争时,由内核态进行仲裁,内核通过用户态传来的futex参数来判断是唤醒读者还是写者。
读写锁的用例场景比较多,发生竞争时:读优先,还是写优先?同优先级读者写者哪个应该先拿到?不同优先级的读者写者,哪个先拿到?如果读者或写者设置了锁优先级继承,又会怎样?读者还涉及递归拿锁,等等等。
此项用例,需要根据posix标准,以及内核的对应实现,在下结论。

猜你喜欢

转载自blog.csdn.net/y33988979/article/details/82256028