天天看点

Linux多线程实践(6) --Posix读写锁解决读者写者问题

读写锁与互斥量类似, 不过读写锁允许更高的并行性. 读写锁用于读称为共享锁, 读写锁用于写称为排它锁;

读写锁规则:

  只要没有线程持有给定的读写锁用于写, 那么任意数目的线程可以持有读写锁用于读;

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

  自旋锁类似于互斥锁, 它的性能比互斥锁更高;

  自旋锁与互斥锁很重要的一个区别在于: 线程在申请自旋锁的时候, 线程并不会挂起, 它总是处于忙等待的状态(一直在自旋, CPU处于空耗的状态);

  自旋锁可用于以下情况:锁被持有的时间短, 而且线程并不希望在重新调度上花费太多的成本.

  自旋锁通常作为底层原语用于实现其他类型的锁: 比如有些互斥锁的实现在试图获取互斥量的时候会自旋一小段时间, 只有在自旋计数到达某一阈值的时候才会休眠; 因此, 很多互斥量的实现非常搞笑, 以至于应用程序采用互斥锁的性能与曾经采用过自旋锁的性能基本上是相同的.

  因此, 自旋锁只在某些特定的情况下有用, 比如在用户层, 自旋锁并不是非常有用, 除非运行在不允许抢占的实时调度类中.

问题描述

  一个数据对象可以为多个并发进程所共享。其中有的进程可能只需要读共享对象的内容,而其他进程可能要更新共享对象的内容。

    读者:只对读感兴趣的进程;

    写者:其他进程(只写,或既读又写);

  规则

    允许多个读者同时读取数据;

    只有一个写者可以写数据;

    写者在写时读者不能读,反之亦然。

  “读者优先”思想小结: 读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。该算法只要还有一个读者在活动,就允许后续的读者进来,该策略的结果是,如果有一个稳定的读者流存在,那么这些读者将在到达后被允许进入。而写者就始终被挂起,直到没有读者为止.

继续阅读