1.4 读者-写者问题
Bob和Alice都十分喜爱自己的宠物,于是决定彼此之间交流一些与宠物相关的信息。Bob在屋子前面竖起了一块公告牌。公告牌上可以粘贴一串很大的瓷片,每个瓷片上只能写下一个字母。空闲的时候,Bob采用一次贴上一块瓷片的方式,通过公告牌传递信息。Alice一有空就用望远镜看Bob在公告牌上留的信息,一次也只读一块瓷片上的内容。
这种方法听起来似乎是一种可行的方案,其实不然。我们来分析这样的场景:假设Bob传递了信息:
Alice通过望远镜誊抄到
恰恰此刻,Bob取下了所有的瓷片又全部写上新信息:
Alice接着继续扫描公告牌,最后誊抄到信息
结果可想而知。
还有其他一些简单明了的方法可以解决读者-写者问题。
Alice和Bob可以利用互斥协议来确保Alice只能读到完整的语句。然而,她可能漏掉某个语句。
他们可以使用啤酒罐-绳子协议,Bob生产语句而Alice消费语句。
如果问题这么容易解决,为什么还特意拿出来讲呢?互斥协议和生产者-消费者协议都要求等待:如果参与者一方由于某个不能预测的事情延误了,另一方也必然被延误。在多处理器共享存储器方式下,解决读者-写者问题的一种可行方法就是让每个线程能够获得多个存储单元的瞬间视图。也就是说无需等待就可以获得这样的视图,或者说当这些存储单元的内容正被读取时,无需防止其他的线程修改它们。这种方法在备份、调试以及其他一些场合是十分有用的。令人惊讶的是,的确存在着这种无等待的办法可以解决读者-写者问题。后面将会看到几个这样的例子。