什么是检查并设置用于?(What is Test-and-Set used for?)

2019-07-31 03:49发布

看完检查并设置后的维基百科条目 ,我还是留下一个问题:“什么会测试和设置可以用来做什么?”

我知道,你可以用它来实现互斥(如在维基百科中描述),但它有什么其他用途?

Answer 1:

您可以使用它,你想要做一些工作之后将数据写入内存,并确保另一个线程不覆盖目标,因为你随时开始。 很多锁/无互斥算法,采取这种形式。



Answer 2:

一个很好的例子是“增量”。

说两个线程执行a = a + 1 。 说a与价值开始100 。 如果两个线程都在同一时间(多芯)上运行,既将加载a100 ,递增到101 ,和存储,早在a 。 错误!

随着检查并设置,你说的“设置a101 ,但只有当它目前拥有价值100 ”。 在这种情况下,一个线程将通过这个测试,但对方会失败。 在故障情况下,线程可以重试整个语句,这一次装入a101 。 成功。

这通常比使用互斥,因为速度快:

  1. 在大多数情况下没有竞争条件,所以发生了更新,而无需获得某种互斥的。
  2. 即使碰撞时,一个线程没有被阻塞所有,并为其他线程只是旋,然后重试它比将暂停自己在行一些互斥它的速度更快。


Answer 3:

想象一下你正在编写一个银行应用程序,而应用程序不得不退出十磅的请求(是的,我的英语;)从账户)。 所以,你需要读取当前账户余额到一个局部变量,减去提款,然后写平衡回内存。

但是,如果另一个并发请求你们之间发生读取值,你写出来? 还有那该请求的结果将被首先得到完全覆盖的可能性,以及账户余额将不正确。

检查并设置帮助我们通过检查你的价值覆盖是什么,你认为它应该是解决这个问题。 在这种情况下,您可以检查余额为您阅读原始值。 由于它的原子,它的不可中断所以没有人可以从下你拉地毯出读取和写入之间。

解决同样的问题,另一种方法是取出的存储位置的锁。 不幸的是,锁是极其难以得到的权利,难推理,具有可扩展性问题,并在失败面前表现不好,所以他们不是一个理想的(但绝对实用)的解决方案。 检查并设置方法形成一些软件事务记忆的基础上,其乐观让每一笔交易同时执行,在滚动他们都回来了,如果他们发生冲突的成本。



Answer 4:

基本上,它的使用是完全互斥,因为原子的巨大重要性。 而已。

检查并设置为可以与其他两个指令,非原子和更快(在多处理器系统,当原子负有硬件开销)执行的操作,所以一般你不会使用它的其他原因。



Answer 5:

当你需要得到一个共同的价值,用它做什么,并更改该值它的使用,假设另一个线程尚未改变了它。

至于实际应用,最后一次见到它是在并发队列(队列可以推/多线程弹出,而无需信号灯或互斥)的实现。

为什么要使用检查并设置而非互斥? 因为它通常需要比互斥的开销更少。 其中一个互斥需要OS介入,一检查并设置可被实现为在CPU上的单一原子指令。 当与线程100的并行环境中运行,在代码关键部分的单一互斥体可能会导致严重的瓶颈。



文章来源: What is Test-and-Set used for?