读写锁的概念

读写锁(pthread_rwlock_t)是用于在多线程环境中协调对共享资源的并发访问的一种同步机制。它允许一个写者或多个读者同时访问共享资源,但不能同时存在一个写者和一个读者或多个写者。在读写锁中,读操作是互斥的,写操作也是互斥的,但读和写操作之间是互斥的。以下是读写锁的详细解释,包括如何确保互斥性。

读写锁的基本概念:

1、读锁(Read Lock):允许多个读者同时持有读锁。如果当前没有写者持有写锁,那么读者可以获取读锁。读取操作期间,不允许写者获得写锁。

2、写锁(Write Lock):写锁是独占的,在同一时间只能有一个线程持有写锁。写锁禁止任何其它读者或写者访问共享资源。如果有读者或写者当前持有锁,写者必须等待直到它们释放锁。

互斥的具体实现在读写锁的实现过程中,需考虑以下几点以确保互斥性:

1、状态变量:__readers:持有读锁的线程数量。__writers:是否有线程持有写锁(通常为0或1)。

2、锁变量:__wrphase_futex 和 __writers_futex:用于同步写操作和管理等待写锁的线程队列。其他辅助变量(如 __cur_writer 等)。

读写锁操作的实现原理:

1、获取读锁:检查当前是否有任何写者持有写锁(即 __writers 是否为 0)。
     (1)若没有写者持有写锁,则增加 __readers 计数器,并获取读锁。
     (2)若有写者持有写锁,则当前线程需要等待该写者释放写锁。

2、释放读锁:

(1)减少 __readers 计数器。
(2)如果所有读线程均已释放读锁(__readers 变为 0),并且有等待的写线程,则唤醒一个写线程。

3、获取写锁:

(1)检查当前是否有任何读者或写者持有读锁或写锁(即 __readers 和 __writers 是否均为 0)。
(2)若没有其他线程持有锁,则设置 __writers 为 1,并且记录当前线程持有写锁。
(3)若有其他线程持有锁,则当前线程需要等待,直到所有读者和写者都释放锁。

4、释放写锁:

(1)将 __writers 计数器重置为 0,表明写锁已经释放。
(2)唤醒在队列中等待的读线程或写线程。

注意pthread_rwlock_t 的使用

1、一个线程嵌套使用读锁,会导致,再次加写锁时锁死(两次读锁两次释放后,再添加写锁)。因为读锁重复嵌套,readers不会增加,释放锁的时候会把readers减翻。pthread_rwlock_t不支持嵌套使用!!!。

2、一个线程写锁嵌套读锁,不会在读锁处锁死,下次添加写锁的时候会锁死。

3、一个线程写锁嵌套写锁,也不会锁死。下次添加写锁的时候会锁死。

pthread_rwlock_t 是 POSIX 线程库中用于实现读写锁的一个数据结构,其内部结构和字段可能会根据实现的不同而有所差异。以下是对你提到的具体字段的解释,这些字段可能是基于某个实际的实现(如 GLIBC):

{ __data =

  { __readers = 0, // 持有读锁的线程数量

__writers = 0, // 持有写锁的线程数量(通常是0或1,因为只允许一个写者)

__wrphase_futex = 0, // 用于写者阶段的 Futex(快速用户级互斥体)

__writers_futex = 0, // 用于等待写者的

Futex __pad3 = 0, // 用于内存对齐和填充

__cur_writer = 0, // 当前持有写锁的线程 ID

__shared = 0, // 指示锁是否在进程间共享

__rwelision = 0 '\000', // 用于读写锁消除(elision),优化锁的实现

__pad1 = "\000\000\000\000\000\000", // 内存对齐和填充

__pad2 = 0, // 内存对齐和填充 __flags = 0 // 额外的标志位,用于记录锁的状态信息

}

}

字段解释:

  1. __readers:

    • 保存当前持有读锁的线程数量。多个线程可以同时持有读锁,因此这是一个计数器。
  2. __writers:

    • 保存当前持有写锁的线程数量。通常情况下,这应该是 0 或 1,因为一次只能有一个线程持有写锁。
  3. __wrphase_futex:

    • 这是一个用于写者阶段的 Futex(快速用户级互斥体),用于实现高效的等待和唤醒机制。
  4. __writers_futex:

    • 这也是一个 Futex,用于管理等待写者的情况。当一个线程需要获取写锁但当前被其他读者或写者持有时,它可能会在这个 Futex 上等待。
  5. __pad3:

    • 用于内存对齐和填充,以确保结构体在不同平台上的高效访问。
  6. __cur_writer:

    • 当前持有写锁的线程 ID。这个字段帮助识别哪个线程当前持有写锁。
  7. __shared:

    • 指示这个锁是否在进程间共享。不同进程间共享的锁需要一些额外的处理和同步。
  8. __rwelision:

    • 这个字段用于读写锁消除(elision),这是一种优化技术,试图减少锁操作的开销。
  9. __pad1:

    • 内存对齐和填充数组,用于确保结构体在不同平台上的高效访问。
  10. __pad2:

    • 同样用于内存对齐和填充。
  11. __flags:

    • 额外的标志位,用于记录锁的状态信息,可以用于标识不同的锁定模式或状态。

这些字段的存在和使用使得 pthread_rwlock_t 能够高效地管理读写锁的状态,支持多线程环境下的读写操作。请注意,以上解释只是基于你提供的字段的一种可能实现,不同的系统和库(如 GLIBC 版本)的实现细节可能有所不同。对于实际开发,尤其是跨平台开发,建议通过标准的 API 来操作这些锁,而不是直接操作或者依赖这些内部实现细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值