当前位置:  开发笔记 > 人工智能 > 正文

什么是测试和设置用于?

如何解决《什么是测试和设置用于?》经验,为你挑选了3个好方法。

在阅读了测试和设置维基百科条目后,我仍然留下了"测试和设置将用于什么?"的问题.

我意识到你可以使用它来实现Mutex(如维基百科中所述),但它有什么其他用途?



1> Jason Cohen..:

一个很好的例子就是"增量".

说两个线程执行a = a + 1.说a从值开始100.如果两个线程同时运行(多核),则两者都将加载a100,递增101并将其存储回来a.错误!

通过测试和设置,您说"设置a101,但仅当它具有当前值时" 100.在这种情况下,一个线程将通过该测试,但另一个线程将失败.在失败的情况下,线程可以重试整个语句,这次加载a101.成功.

这通常比使用互斥锁更快,因为:

    大多数情况下没有竞争条件,所以更新发生时无需获取某种互斥量.

    即使在碰撞过程中,一个线程根本就不会被阻塞,而另一个线程旋转和重试的速度要快于为某些互斥锁暂停自身的速度.


@ jason-cohen:这实际上是对[比较和交换](https://en.wikipedia.org/wiki/Compare-and-swap)的描述.测试和设置通常仅涉及值0和1.**set**部分是指将指定内存位置的值设置为1.它返回先前的值,1或0,并执行所有这些操作在单个原子操作中.
@GregSlepak是正确的,这是compare_and_swap.test_and_set()接受一个指向目标的布尔指针,将其设置为TRUE并返回指针的原始值.如果test_and_set(&lock)的返回值(即&lock的原始值)为true,那么我们进入临界区.

2> moonshadow..:

您可以在执行某些操作后随时将数据写入内存,并确保自启动以来另一个线程未覆盖目标.许多锁定/互斥锁算法采用这种形式.



3> HenryR..:

想象一下,您正在编写银行应用程序,并且您的应用程序要求从帐户中提取10英镑(是的,我是英语;)).因此,您需要将当前帐户余额读入本地变量,减去提款,然后将余额写回内存.

但是,如果您在读取值并将其写出之间发生另一个并发请求,该怎么办?该请求的结果可能会被第一个完全覆盖,并且帐户余额将不正确.

测试和设置通过检查您的覆盖值是否符合您认为应该是的值来帮助我们解决该问题.在这种情况下,您可以检查余额是否是您阅读的原始值.因为它是原子的,所以它是不可中断的,所以没有人可以在读取和写入之间从你身下拉出地毯.

解决同一问题的另一种方法是取消内存位置的锁定.不幸的是,锁定非常难以正确,难以推理,存在可扩展性问题并且在面对失败时表现不佳,因此它们不是理想的(但绝对实用的)解决方案.测试和设置方法构成了一些软件事务存储器的基础,它们乐观地允许每个事务同时执行,但是如果它们发生冲突则以将它们全部回滚为代价.

推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有