zoukankan      html  css  js  c++  java
  • OS | 读写锁【摘】

    读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。

    互斥锁与读写锁的区别:

    当访问临界区资源时(访问的含义包括所有的操作:读和写),需要上互斥锁;

    当对数据(互斥锁中的临界区资源)进行读取时,需要上读取锁,当对数据进行写入时,需要上写入锁。

    读写锁的优点:

    对于读数据比修改数据频繁的应用,用读写锁代替互斥锁可以提高效率。因为使用互斥锁时,即使是读出数据(相当于操作临界区资源)都要上互斥锁,而采用读写锁,则可以在任一时刻允许多个读出者存在,提高了更高的并发度,同时在某个写入者修改数据期间保护该数据,以免任何其它读出者或写入者的干扰。

    读者-写者问题和生产者-消费者问题不同的是,后者的每个线程都要修改缓冲区的内容,所以不得不使用互斥锁来保证数据一致性,而前者有些线程是只读的,多个只读线程同时访问并不会出现数据不一致的情况,所以在实现上不必为每个线程都加一个互斥锁,而是让多个读线程可以同时访问,只有写进程的访问是互斥的。

    这一篇博文写的很详细:http://ouonline.net/pthread-notes-3

    写者优先的思考参考了:http://blog.csdn.net/yaozhiyi/article/details/7563869

    读者优先:第一次读的时候获取锁,最后一次读的时候释放锁;这样只要有读操作,就不能写;

    写者优先:

    1. 对于写者:只要有写操作,就会尝试着去获取读锁,这样接下来的读就不能继续了,这样的尝试只需要一次,当没有写操作时就应该释放读锁。

    2. 对于读者:只要有读操作,那么就尝试着去获取写锁,这样接下来的写也就不能继续,但是读者还是可以读;读操作会和写操作竞争读锁,这里确保了只有一个读操作和写操作竞争读锁;


    关于写者优先,我的思路如下:

    a. 需要写写互斥,所以需要下面的结构:

    1 //写者
    2 lock(&writeLock);
    3 write();
    4 unlock(&writeLock);

    b. 需要读写互斥,所以:

     1 //写者;并且只需要第一个写请求去获取读锁
     2 lock(&writeCountLock);
     3 writeCount++;
     4 if (writeCount == 1) lock(&readLock);
     5 unlock(&writeCountLock);
     6 
     7 lock(&writeLock);
     8 write();
     9 unlock(&writeLock);
    10 
    11 unlock(&readLock);
    12 
    13 lock(&writeCountLock);
    14 writeCount--;
    15 if (writeCount == 0) unlock(&readLock);
    16 unlock(&writeCountLock);
    1 //读者
    2 lock(&readLock);
    3 read();
    4 unlock(&readLock);

    c. 在读的时候,应该获取写锁,这样才能保证读的时候不写;但这是没有写操作时的处理;

     1 //读者
     2 lock(&readCountLock);
     3 readCount++;
     4 if (readCount == 1) lock(&writeLock);
     5 unlock(&readCountLock);
     6 
     7 read();
     8 
     9 lock(&readCountLock);
    10 readCount--;
    11 if (readCount == 0) unlock(&writeLock);
    12 unlock(&readCountLock);

    d. 如果此时有一个新的写操作,为了让它能够竞争到读锁,那么要让新来的read锁住,很明显就是在read()的前面要锁住,而且是和读锁相关,并且是限定了竞争时读的个数为1.所以加在Line2-5的外围。

    // 读者
    lock(&readLock);
    lock(&readCountLock);
    readCount++;
    if (readCount == 1) lock(&writeLock);
    unlock(&readCountLock);
    unlock(&readLock);
    
    read();
    
    lock(&readCountLock);
    readCount--;
    if (readCount == 0) unlock(&writeLock);
    unlock(&readCountLock);

    这样是能保证,没有新的读的时候,永远只是竞争一个读锁来更新readCount,然后read()这里是可以并行的。

  • 相关阅读:
    UVALive 6909 Kevin's Problem 数学排列组合
    UVALive 6908 Electric Bike dp
    UVALive 6907 Body Building tarjan
    UVALive 6906 Cluster Analysis 并查集
    八月微博
    hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形
    hdu 5792 World is Exploding 树状数组
    hdu 5791 Two dp
    hdu 5787 K-wolf Number 数位dp
    hdu 5783 Divide the Sequence 贪心
  • 原文地址:https://www.cnblogs.com/linyx/p/3969566.html
Copyright © 2011-2022 走看看