这里在生产者的代码中,当它获取到互斥锁时,若发出信号唤醒消费者,则此时可能系统立即调度唤醒消费者,但互斥锁任然在生产者之手,则消费者获取互斥锁必然失败,为了避免此种低效的情况出现,我们可以直到生产者释放互斥锁后才给与之关联的条件变量发送信号,这在Posix里是可以这么做的,但Posix又接着说:若要可预见的调度行为,则调用pthead_cond_signal的线程必须锁住该互斥锁。

当在进程间共享互斥锁时,持有该互斥锁的进程可能在持有期间终止,但无法让系统在终止时自动释放掉所持有的锁。一个线程也可以在持有互斥锁期间终止,可能是自己调用pthread_exit或被另一个线程取消,若是前者,则它应该知道自己还有一个互斥锁,若是后者,则该线程可以先安装一个将在被取消时调用的清理处理程序。但最致命的情况是由于此线程的终止导致整个进程的终止。即使一个进程终止时系统自动释放其持有的锁,但也会导致临界区内数据处于不一致状态,

读写锁的规则:

1,只要没有线程持有某个给定的读写锁用于写,则任意数目的线程可以持有

该读写锁用于读


2
,仅当没有线程持有某个给定的读写锁用于读或用于写时,才能分配该读写锁用于写


这种锁在那些读数据比写数据频繁的应用中使用比较有用,允许多个读者提供了更高的并发度,同时在
写者修改数据时保护数据,避免任何其他读者或写者的干扰。

这种对某个给定资源的共享访问也叫共享独占上锁,获取一个读写锁用于读称为共享锁,获取一个读写锁用于写称为独占锁。在操作系统中就介绍过这种,经典的问题就是读者写者问题,有多种类型:多读者,单写者或多读者,多写者。,此外还有要考虑的就是读者和写者谁优先,也就产生了1类和2类读写问题。

      读写锁类型为pthread_rwlock_tpthread_rwlock_rdlock获取一个读出锁,若对应的读写锁已经被某个写者持有,则阻塞调用线程,pthread_rwlock_wrlock获取一个写出锁,若对应的读写锁已经被另一个写者持有或被一个或多个读者持有,则阻塞调用线程,pthread_rwlock_unlock释放一个读出锁或写入锁。

      使用互斥锁和条件变量实现读写锁(写者优先)


《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_init(pthread_rwlock_t *rw, pthread_rwlockattr_t *attr)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_destroy(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_rdlock(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_wrlock(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_unlock(pthread_rwlock_t *rw)

《UNIX网络编程 卷2》读书笔记(四)int pthread_rwlock_unlock(pthread_rwlock_t *rw)

这里的读出锁和写入锁函数都有一个问题,若调用线程阻塞在pthread_cond_wati调用上,并且随后此线程被取消了,则它会在还持有互斥锁的情况下终止,于是rw_nwaitreaders计数器的值会出错

相关文章:

  • 2021-06-20
  • 2021-10-30
  • 2022-03-07
  • 2021-09-29
  • 2022-02-22
  • 2021-12-06
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-14
  • 2021-12-11
  • 2021-09-24
相关资源
相似解决方案