• 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()这里是可以并行的。

  • 相关阅读:
    关于代码风格
    python笔记-glob模块
    python笔记-mysql安装与配置
    python笔记-shutil模块
    python笔记-os模块
    python笔记-内存分析
    python笔记-装饰器
    python笔记-正则表达式
    python笔记-迭代器-生成器-对象生成式
    python笔记-模块和包
  • 原文地址:https://www.cnblogs.com/linyx/p/3969566.html
Copyright © 2020-2023  润新知