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

什么是读者-写者问题?

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

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

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

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

分析

多个读进程可以并发读数据集,因此用一个变量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进行查询时,所有的发送弹幕请求都需要被挂起。而当有发送弹幕请求正在被处理时,所有的弹幕查询请求也需要被挂起。

多面墙的查询问题的解决

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容