gpt4 book ai didi

c# - 简单的线程问题,锁定对共享资源或整个功能的访问?

转载 作者:行者123 更新时间:2023-11-30 15:45:46 26 4
gpt4 key购买 nike

这是对我之前的一个问题的解释。这是一个简单的线程问题,但我似乎无法理解。

如果我有共享代码:

private static object objSync = new object();
private int a = 0;

public void function()
{
lock(objSync)
a += 2;

lock(objSync)
a += 3;
Console.WriteLine(a.ToString());
a=0;
}

我不能期望 'a' 最后等于 5,因为第一个线程获得锁将 'a' 设置为 2 然后下一个线程可以在第一个线程之前获得锁将其设置为 '4'可以加 3,最后你会得到 7。

据我所知,解决方案是在整个事情上加一把锁,然后你总是可以期望 5。现在我的问题是,如果在这两个锁之间有一百万行代码怎么办。我无法想象锁定一百万行代码。您将如何确保线程安全而不是通过锁定大约一百万零两行代码来降低性能?

编辑:

这是我为题写的废话代码。实际应用是线路监控系统。有两个屏幕显示当前线路,一个用于职员,一个用于公众。店员的屏幕通过串行端口接受“点击”,串行端口逐行显示,然后通过通知事件更新公共(public)屏幕(请参阅观察者设计模式)。问题是如果您向答题器发送垃圾邮件,它们将不会同步。我想发生的事情是第一个屏幕添加到行号,显示它然后更新公共(public)屏幕,但是在公共(public)屏幕有机会显示数据库中的行号之前,店员再次点击并且数字消失了同步。上面的 'a' 代表我从数据库中检索到的值,而不仅仅是一个简单的 int。有几个地方我更改了值,我需要所有这些都以原子方式发生。

最佳答案

这完全取决于您对“成功”的定义。如果它是一个计数器,那仍然可能是正确的结果。如果您只想更新它,如果它是您认为的,那么在第一个锁内拍摄快照,并同样与最后一个锁中的快照进行比较。在那种情况下,您可以用一些 Interlocked.CompareExchange 替换大部分代码。同样,在“计数器”场景中,Interlocked.Increment 是您的 friend 。

如果代码必须匹配,那么您有几个选择:

  • 如果比较失败,再次运行整个百万行;重复直到你赢得比赛(通过匹配)
  • 如果比较失败,抛出异常
  • 为百万行提供 block ;它可能仍然是一百万行...
  • 想出一些对您的场景有意义的其他解决策略

在前两个中,您应该通过将任何相关数据留在中间状态来观察污染事物。

顺便说一句;对 0 的最终赋值可能是同一锁定策略的一部分。锁只有在所有访问都尊重它们的情况下才有效。

但只有您的情景才能告诉我们冲突中“正确”的行为是什么。

关于c# - 简单的线程问题,锁定对共享资源或整个功能的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4912356/

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