zoukankan      html  css  js  c++  java
  • 读者写者问题

    1. 读者写者问题
    读者优先: 只要有一个Reader处于活动状态, 那么后面来的Reader都会被接纳. 若Reader源源不断, 那么Writer就会一直处于阻塞状态, 即写者被饿死.

    写者优先: 一旦Writer就绪, 就会先执行Writer, 写者优先级高于读者, 若Writer源源不断, 那么Reader就会一直处于阻塞状态, 即读者被饿死.

    2. 信号量 - 读者优先

    数据结构

    1 data // 共享数据
    2 CountMutex = 1 // 保证Rcount互斥
    3 WriterMutex = 1 // 读者写者互斥
    4 Rcount = 0 // 读者数量

    写者

    1 sem_wait(WriterMutex);
    2 
    3 write data;
    4 
    5 sem_post(WriterMutex);

    读者

     1 sem_wait(Rcount);
     2 // 第一个读者进入, 获取共享区操作权限
     3 if (Rcount == 0) sem_wait(WriterMutex);
     4 ++Rcount;
     5 sem_post(Rcount);
     6 
     7 read data;
     8 
     9 sem_wait(Rcount);
    10 --Rcount;
    11 // 最后一个读者退出, 释放共享区操作权限
    12 if (Rcount == 0) sem_post(WriterMutex);
    13 sem_post(Rcount);

    3. 管程 - 写者优先

    数据结构

    AR = 0 // 正在读的读者
    AW = 0 // 正在写的写者
    WR = 0 // 正在等待的读者
    WW = 0 // 正在等待的写者
    Condition okToRead // 条件变量: 可读
    Condition okToWrite // 条件变量: 可写
    Lock lock // 线程互斥锁

    读者

     1 public Database::Read() {
     2     // wait until no writer
     3     StartRead();
     4 
     5     read database;
     6     
     7     // check out - wake up waiting writers
     8     DoneRead();
     9 }
    10 
    11 private Database::StartRead() {
    12     lock.Acquire();
    13     // 若存在正在写或正在等待的写者, 就将读者加入等待队列中
    14     while ((AW + WW) > 0) {
    15         WR++;
    16         okToRead.wait(&lock); // 睡眠, 被唤醒后从这里开始执行
    17         WR--;
    18     }
    19     // 允许同时存在多个读者
    20     AR++;
    21     lock.Release();
    22 }
    23 
    24 private Database::DoneRead() {
    25     lock.Acquire();
    26     AR--;
    27     // 若最后一个正在读的读者退出且有写者在排队, 那么就唤醒一个写者
    28     if (AR == 0 && WW > 0) {
    29         okToWrite.signal(); // 唤醒一个写者
    30     }
    31     lock.Release();
    32 }

    写者

     1 public Database::Write() {
     2     // wait until no readers or writers
     3     StartWrite();
     4 
     5     write database;
     6 
     7     // check out - wake up waiting writers or readers
     8     DoneWrite();
     9 }
    10 
    11 private Database::StartWrite() {
    12     lock.Acquire();
    13     // 若存在正在操作数据库的对象, 就等待
    14     // 由于 AW 也包含, 所以一次只允许一个读者操作数据库
    15     while ((AW + AR) > 0) {
    16         WW++;
    17         okToWrite.wait(&lock);
    18         WW--
    19     }
    20     AW++;
    21     lock.Release();
    22 }
    23 
    24 private Database::DoneWrite() {
    25     lock.Acquire();
    26     AW--;
    27     // 若存在正在等待的写者, 则唤醒随机一个
    28     if (WW > 0) { // 条件1
    29         okToWrite.signal();
    30     }
    31     // 若条件1不满足且存在正在等待的读者, 则唤醒全部正在等待的读者
    32     else if (WR > 0) {
    33         okToWrite.broadcast();
    34     }
    35     lock.Release();
    36 }
  • 相关阅读:
    YARN架构设计详解
    HDFS文件上传
    HDFS Namenode启动过程
    (转)计算机原理学习(1)-- 冯诺依曼体系和CPU工作原理
    (转)python之from_bytes、to_bytes
    (转)Python3入门之线程threading常用方法
    (转)Python3.5 queue模块详解
    (转) argparse — 解析命令参数和选项
    (转)Python3之pickle模块
    (转)linux用户态和内核态理解
  • 原文地址:https://www.cnblogs.com/shaohsiung/p/9977690.html
Copyright © 2011-2022 走看看