- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
using System;
using System.Threading;
using System.Threading.Tasks;
namespace _1._41_Compare_and_Exchange_as_a_nonAtomic_operation
{
public class Program
{
static int value = 1;
public static void Main()
{
Task t1 = Task.Run(() =>
{
if (value == 1)
{
Thread.Sleep(1000);
value = 2;
}
});
Task t2 = Task.Run(() =>
{
value = 3;
});
Task.WaitAll(t1, t2);
Console.WriteLine(value); //Displays 2
}
}
}
我正在尝试将上述非原子操作转换为原子操作,方法是:
Interlocked.CompareExhange(ref value, newValue, compareTo);
我写成
Interlocked.CompareExhange(ref value, value, value); //This doesn't look right!
和
Interlocked.CompareExhange(ref value, t2, t1); //will not compile
问题
Interlocked.CompareExchange
被使用? 最佳答案
With or without Interlocked.CompareExchange value is output as 2? Why?
真正的答案是:巧合。您的代码是不确定的,其行为取决于操作系统线程调度程序。
但是... t1
实际上一点也不奇怪在 t2
之前开始执行.在这种情况下,if (value == 1)
检查在 t2
之前进行有机会执行value = 3;
.
综上所述,最有可能的时间线是:
t1
: value
根据 1
检查t1
: t1
睡一秒钟t2
: value
设置为 3t1
: 一秒钟后醒来t1
: value
设置为 2但是正如我上面所说的,这只是实际发生的情况,但是游览代码仍然是不确定的,如t2
可以原则上在t1
之前开始执行.
What is the correct way to reference t1, t2?
如果我正确理解你的问题,你的做法似乎是正确的。
Why can't I reference the output of the task directly? (value, t2, t1)
你开始void
任务,它们一开始就没有输出。它们由 Task
表示类型。
您可以启动一个返回如下结果的任务:
var t = Task.Run(() => {
// do anything
return 42;
});
在这种情况下,t
将是 Task<int>
类型你将能够访问它的 Result
任务结束时的属性(如果您尝试在任务完成之前访问 i,它将阻塞直到任务结束)。
Is some sort of conversion required or even necessary?
我不确定我是否理解您的问题。
As I understand the value should be updated to 2 (value =1) then updated to 3 instead of the current output (value =1, updates to 3 then updates it to 2) once Interlocked.CompareExchange is used?
差不多,是的。 Interlocked.CompareExchange
是原子的。它将执行比较并在硬件级别一步设置值:
Interlocked.CompareExchange(ref value, 2, 1);
这是原子等价于:
if (value == 1)
value = 2;
如果您这样做,最终值将始终为3
.因为可能有两种不同的场景(这很容易,因为现在两个任务都包含一个原子语句):
t1
在 t2
之前执行:
t1
: value
根据 1
检查,这是真的,所以 value
设置为 2
t2
: value
设置为 3 t2
在 t1
之前执行:
t2
: value
设置为 3 t1
: value
根据 1
检查,这是错误的,所以 value
保持不变如您所见,您最终会得到 3
在这两种情况下。
关于c# - Interlocked.CompareExchange(引用值,newValue,compareTo),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34559084/
Interlocked.CompareExchange() 方法 ( docs ) 粗略地说: “我有一个变量,我想我知道它当前有什么值。如果我是对的,请将值更改为那个”。 关键是这个方法可以用来在多
伙计们, 我希望您评估下面的下一个代码。如您所见,我使用 Interlocked.CompareExchange,在这种情况下有意义吗? (我不确定它是否正确)。 如果有任何注释、评论等,我将很高兴。
我的目标是: 有一定范围的整数,我必须测试该范围内的每个整数是否随机。我想为此使用多个线程,并使用共享计数器在线程之间平均分配工作。我将计数器设置为初始值,让每个线程取一个数,增加它,进行一些计算,然
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Interlocked.CompareExchange using GreaterThan or LessT
我想知道是否有可能将以下代码中的初始值重新排序为在计算之后导致未定义的行为。 以下例子摘自https://learn.microsoft.com/en-us/dotnet/api/system.thr
以下语句(寻址与第一个和第三个参数相同的变量)是否总是会导致变量 b 在完成时获取变量 c 的值,或者另一个线程是否有可能在获取参数时更改一个或多个参数在比较操作期间导致第一个和第三个参数包含不同的值
编译器或处理器能否重新排序以下指令,以便另一个线程看到 a == 0 和 b == 1? 假设 int a = 0, b = 0; 某处。 System.Threading.Interlocked.C
我遇到了 .NET 3.5 的 ConcurrentDictionary 实现(很抱歉我现在可以找到链接),它使用这种锁定方法: var current = Thread.CurrentThread.
我正在尝试使用 Interlocked.CompareExchange使用此枚举: public enum State { Idle, Running, //... } 以下代
我正在阅读 Joe Duffy 关于 Volatile reads and writes, and timeliness 的帖子,我正在尝试了解帖子中最后一个代码示例的一些内容: while (Int
假设你有一个属性public Foo Bar { get; } 你想延迟初始化。一种这样的方法可能是使用 Interlocked 类,它保证某些操作序列(例如递增、添加、比较交换)的原子性。你可以这样
我需要递增一个计数器直到它达到一个特定的数字。我可以使用两个并行任务来增加数字。我没有使用锁来检查数字是否未达到最大允许值然后递增,而是使用 Interlocked .CompareExchange
System.Threading.Interlocked.CompareExchange 运算符提供比较和交换操作的原子(因此线程安全)C# 实现。 例如int i = 5; Interlocked.
以下示例来自 MSDN . public class ThreadSafe { // Field totalValue contains a running total that can be
using System; using System.Threading; using System.Threading.Tasks; namespace _1._41_Compare_and_Exc
我有一个整数数组,用于跟踪 10,000 个并发任务的完成情况,其中值为 1 或 0。我认为如果这个数组是一个位数组并且每个并发线程都使用 interlocked 会更有效率。CompareExcha
来自 https://msdn.microsoft.com/en-us/library/bb297966(v=vs.110).aspx [ComVisibleAttribute(false)] pub
免责声明:我的帖子显然总是很冗长。如果您碰巧知道标题问题的答案,请随意回答,而无需阅读我下面的扩展讨论。 System.Threading.Interlocked类提供了一些非常有用的方法来帮助编写线
概要: 在我看来,这: 将表示逻辑状态的字段包装到单个不可变的消耗对象中 通过调用Interlocked.CompareExchange 更新对象的权威引用 并适当地处理更新失败 提供了一种并发性,不
在Link.TryAdd方法的dapper代码中,有如下一段代码: var snapshot = Interlocked.CompareExchange(ref head, null, null);
我是一名优秀的程序员,十分优秀!