美文网首页
读者-写者问题的应用——多面墙的查询问题

读者-写者问题的应用——多面墙的查询问题

作者: 江俊广 | 来源:发表于2018-12-13 23:48 被阅读0次

什么是读者-写者问题?

读者-写者问题是指多个进程对一个共享资源即数据集(如文件或记录集)进行读写操作的问题。把只要求读数据的进程称为读进程,把要求修改数据的进程称为写进程。多个读进程可以同时读此数据集,不需要互斥也不会产生问题,不存在破坏数据完整性、正确性的问题,但是一个写进程不能与其他进程(不管是读进程还是写进程)同时访问此数据集,它们之间必须互斥,否则会破坏数据集的完整性。

解决读者-写者问题的意义

理论上,直接对数据集加锁,就可以实现对多进程时数据集的访问保护。但是在一段时间内并没有写进程,只有较多的读进程的话,对数据集的加锁是不必要的,反而会降低系统的性能。因此读者-写者问题的提出是为了在上述场景下,兼顾数据集访问安全和效率。

读者-写者问题的解决方法

分析

多个读进程可以并发读数据集,因此用一个变量rc记录并发读数据集的进程数。当rc≥1时,禁止写进程对数据集进行写操作,当rc=0时,允许写进程对数据集进行写操作。

rc对于读进程而言,是一个临界资源,因此设置一个互斥信号量mutex,防止多个读进程同时修改rc的值。

数据集对于写进程而言是一个临界资源,因此设置一个互斥信号量db。

相关变量总结

  • mutex: 保护对rc的访问,初值为1

  • db: 控制写进程对数据集的访问,初值为1

  • rc: 公共变量,记录读进程的个数

同步算法

Semaphore mutex=1;  //保护对rc的访问
Semaphore db=1;  //控制对数据集的访问
int rc=0;  //读数据集的读进程个数

main()
{
  Cobegin  //两个进程并发执行
    reader();
    writer();
   Coend
}

void reader()  //读者进程
{
  while(true){
    P(mutex);  //互斥对rc的访问
    rc = rc + 1;  //增加一个读进程数
    if(rc == 1){  //当第一个读进程读数据集时,阻止写进程写
      P(db);
    }
    V(mutex);  //恢复对rc的访问
    读数据集
    P(mutex);  //互斥对rc的访问
    rc = rc - 1; //读者减少一个
    if(rc == 0){  //当最后一个读进程读完数据集时,允许写进程写
      V(db);
    }
    V(mutex);  //恢复对rc的访问
  }
}

void writer() //写者进程
{
  while(true){
    P(db);  //排斥访问数据集
    写数据集;
    V(db);  //恢复对数据集的访问
  }
}

运行分析

当一个读进程在使用数据集时,其他读进程也可以同时进行读操作,读进程的个数由rc来衡量。
此时,如果有一个写进程到来,由于rc>0,因此写进程被挂起,知道所有读进程都结束时,写进程才可以开始写操作。

当一个写进程在写操作时,其他进程(包括读进程和写进程)都会被挂起,直到当前写进程完成。

上述算法确实可以解决读者-写者问题,当然也导致一个潜在的问题——只要有读进程陆续到来,写进程就会被一直挂起直到没有一个读进程为止,因此上述算法也被称为以读者为优先的算法。感兴趣的读者还可以查看以写者为优先的算法

多面墙的查询问题

笔者在实现弹幕系统的过程中遇到了如下问题。

观众可以通过微信小程序发送弹幕到服务器。在服务器的数据库中,每条弹幕对应不同的记录,因此发送弹幕的请求不是互斥的。并且为了支持尽可能多的观众同时发送弹幕,发送弹幕的请求并发度需要比较高。

与此同时,有n面弹幕墙向服务器查询最新的弹幕,在某一段时间内,这n面墙应该获取到相同的弹幕。由于n的大小是未知的,让每个弹幕记录是否被某一面墙查询过是比较困难的。因此我们让每一面墙维护一个最近查询时间last_query_time,当其向服务器发送查询请求时,服务器只会返回在last_query_time之后通过审核的弹幕。因此每个弹幕只需要记录审核时间checking_time即可。

当服务器处理墙A的查询请求时,如果有新的弹幕B通过审核,则B在这次查询请求和下次查询请求中都不会返回给墙A。则弹幕B就被遗漏了。为了防止弹幕遗漏的发生,当墙A进行查询时,所有的发送弹幕请求都需要被挂起。而当有发送弹幕请求正在被处理时,所有的弹幕查询请求也需要被挂起。

多面墙的查询问题的解决

通过上述描述,读者不难发现多面墙的查询问题与读者-写者问题非常类似。
发送弹幕请求对应读进程,请求数量多,并且彼此不互斥。
查询弹幕请求对应写进程,请求数量少,并且当有查询弹幕请求时,不允许处理发送弹幕请求;当有发送弹幕请求时,不允许有查询弹幕请求。

相关文章

  • 读者-写者问题的应用——多面墙的查询问题

    什么是读者-写者问题? 读者-写者问题是指多个进程对一个共享资源即数据集(如文件或记录集)进行读写操作的问题。把只...

  • 读者写者问题

    读者写者问题的小总结。。。实际上就是抄书写者优先的情况 读进程优先的情况 二者公平竞争的情况

  • 读者-写者问题

    问题描述 使用信号量进行解决 优先策略选择 读者优先 上述方案为读者优先。因为当读者进行读取的时候,如果后面一直有...

  • 读者写者问题

    读者写者问题是IPC问题的一种典型的代表。 我写了一个实现,这是一个写者优先的实现。一个写者,多个读者的模型。 读...

  • 二.进程(5)信号量习题

    1. 读者与写者(写者优先方式) 2. 黑白棋问题 3. 嗜睡的理发师问题 4. 生产与销售问题 读者与写者问题 ...

  • 苹果 AppStore 发布流程总结

    PS:本文主要简述苹果AppleStore的发布流程,细节问题请读者自行查询。 应用创建等:https://itu...

  • 2020-05-06多线程经典同步问题

    1、生产者消费者问题2、哲学家就餐问题3、读者-写者问题4、熟睡的理发师问题5、三个烟鬼的问题

  • 冷月手撕408之操作系统(10)-经典同步互斥问题

    操作系统的经典同步互斥问题主要是介绍了 几个经典的同步互斥问题,其中搞懂生产者消费者问题、读者写者问题;其他的问题...

  • Go 读写锁

    读写锁sync.RWMutext实现读者写者问题

  • 第2章 2-5信号量习题

    1.读者与写者问题(写者优先方式) 读者优先的关键: 若读者先占有互斥信号量,只有最后一个读者离开,计数降为0时...

网友评论

      本文标题:读者-写者问题的应用——多面墙的查询问题

      本文链接:https://www.haomeiwen.com/subject/qdvihqtx.html