操作系统导论习题解答(29. Locked Data Structures)

Lock-based Concurrent Data Structures

带着问题:给定一个数据结构,如何给其添加锁使其拥有正确性和高效性?

1. Concurrent Counters

1.1 Simple But Not Scalable

在这里插入图片描述在这里插入图片描述
上述代码满足了正确性,但是对于性能,我们一无所知。为了了解性能优劣,做了一个基准测试,如下所示(precise)在这里插入图片描述从上图可以看出,单线程性能可以,但是一旦多线程,性能极差!

perfect scaling:多处理器处理多线程性能和单处理器处理单线程性能几乎一样。

1.2 Scalable Counting

一种解决可扩展问题的方法叫approximate counter(近似计数)近似计数的基本思想如下:当在给定内核上运行的线程希望增加计数器时,它会增加其本地计数器,通过相应的本地锁同步对该本地计数器的访问。由于每个CPU都有自己的本地计数器,所以CPU上的线程可以在不用争的情况下更新本地计数器,因此该计数器的更新是可伸缩的。为了使全局计数器保持最新,通过获取全局锁并将其递增本地计数器的值,本地值会定期传输到全局计数器。
看一个例子,定期传输阈值为5。如下所示在这里插入图片描述再看一次下图(approximate)在这里插入图片描述
性能非常好(very good)!

下图展示了传输阈值对性能的影响:在这里插入图片描述
S越小,虽然性能越低,但是全局计数器越精确;S越大,性能越好,但是全局计数器越滞后。(精度/性能不可兼得)

下面是近似计数的代码在这里插入图片描述

2. Concurrent Linked Lists

在这里插入图片描述
对于上述代码,我们能否重写List_Insert()List_Lookup()使其在并发插入情况下避免失败路径也需要调用unlock在这里插入图片描述

2.1 Scaling Linked Lists

一种在list中实现更多并发性的技术:hand-over-hand locking其基本思想如下:不是整个list有一个锁,而是list中的每个node都有一个锁。在遍历list时,代码首先获取下个node的锁,然后释放当前node的锁。

这种方法确实有意义,实现了list操作的高度并发性。但是很难使这种结构比简单的单锁方法快(获取和释放遍历list中每个node的锁太耗时)。

3. Concurrent Queues

在这里插入图片描述
有两个锁,一个队头一个队尾,分别适用于入队和出队。

4. Concurrent Hash Table

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值