gpt4 book ai didi

c# - SemaphoreSlim(1, 1) 是否确保像锁一样从缓存中刷新读取和写入?

转载 作者:行者123 更新时间:2023-12-05 03:26:50 37 4
gpt4 key购买 nike

附加问题

SemaphoreSlim(1, 1) 是否仍然确保我有正确的输出 1000000,即使 task1task2 在 2 个不同的平台上运行核心?

原始问题

考虑以下代码片段,_semaphore 是否与 lock 具有相同的效果?

输出:

  1. 使用锁:1000000
  2. _semaphore = new SemaphoreSlim(1, 1): 1000000(我运行程序10次结果都一样)
  3. _semaphore = new SemaphoreSlim(10, 10):从 999998 到 999990 到 1000000 等不等。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Calculate
{
private int _val = 0;
private object _addLock = new object();
private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
public int Val
{
get
{
return _val;
}
}

public void IncreManyTimes()
{
for (int i = 0; i < 500000; ++i)
{
//lock(_addLock)
//{
// _val = _val + 1;
//}
_semaphore.Wait();
_val = _val + 1;
_semaphore.Release();
}
}
}
class Program
{
static void Main(string[] args)
{
Calculate calculate = new Calculate();
Task.Run(() =>
{
Task task1 = Task.Run(() =>
{
calculate.IncreManyTimes();
});

Task task2 = Task.Run(() =>
{
calculate.IncreManyTimes();
});
Task.WaitAll(task1, task2);
}).Wait();

Console.WriteLine(calculate.Val);

Console.ReadKey();
}
}
}

相关问题:Does locking ensure reads and writes are flushed from caches? If so, how?

我的问题可以描述为:SemaphoreSlim(1, 1) 是否确保从缓存中刷新读取和写入?

最佳答案

does the _semaphore has the same effect as lock?

是也不是。考虑到您的 IncreManyTimes 方法的行为,它确实具有相同的效果(_val = _val + 1; 不会由多个线程同时运行)。

不过,它们有一些不同。例如,lock 始终专用于其执行线程,而 SemaphoreSlim 可以从任何线程释放。这就是为什么 SemaphoreSlim 是“锁定”包含 await 的代码块的一个很好的替代方案(它甚至不会用 lock 编译)因为如果继续在不同的线程上执行,它将无法按预期工作。

进一步说明,如果lock 中出现异常,则锁会被释放。要达到相同的效果,您必须将 _semaphore.Release(); 放在 finally block 中。

此外,SemaphorSlim 是一次性对象,因此您应该考虑在您的Calculate 类中实现IDisposable

最后,我不知道这是否只是一个简化的示例,但在这里您不需要任何这些。您可以通过 Interlocked.Increment(ref _val) 简单地递增,不需要锁定。

编辑:

Does SemaphoreSlim(1, 1) still ensures that I have the correct output 1000000, even if task1 and task2 run on 2 different cpu cores?

是的,因为它一次只允许一个线程进入临界区。

关于c# - SemaphoreSlim(1, 1) 是否确保像锁一样从缓存中刷新读取和写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71638590/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com