c# - 锁能开多深?

标签 c# .net locking thread-safety

我有以下代码:

            locker = new object();
        lock (locker)
        {
            for (int i = 0; i < 3; i++)
                 ver_store[i] = atomic_Poll(power);                
        }

我只是在徘徊,考虑到lock内的函数访问了一些全局资源,(其中一个open socket)对象内的所有全局资源是否也被锁住了。 (我知道访问这些相同变量的任何其他函数也必须对它们实现锁定,以使锁定机制有效。我只是还没想好锁定它们 :) )

最佳答案

lock 语句不会“锁定代码”或大括号之间的任何资源。

我觉得最好从线程的角度去理解锁(毕竟线程场景就是需要考虑锁的时候)

给定您的示例代码

10  locker = new object();
11  lock (locker)
12  {
     ...
15  }

当线程 X 执行到第 10 行时,创建了一个新对象,并在第 11 行获取了对象上的锁。线程 X 继续执行 block 中的任何代码。

现在,当线程 X 在我们的代码块中间时,线程 Y 到达第 10 行。你看,创建了一个新对象,并且由于它是由线程 Y 创建的,因此当前没有在该对象上获取任何锁。因此,当线程 Y 达到 11 时,它将成功获取该对象的锁,并继续与线程 X 并发执行该 block 。

这就是锁应该防止的情况。那么该怎么办? 使储物柜成为共享对象

01  static object locker = new object();

    ...

11  lock (locker)
12  {
     ...
15  }

现在,当线程 X 到达第 11 行时,它将获取锁并开始执行 block 。当线程 Y 到达第 11 行时,它将尝试获取与线程 X 相同的对象的锁。由于该对象已经被锁定,线程 Y 将等待直到锁被释放。从而防止代码块的并发执行,从而保护该代码使用的任何资源被并发访问。

注意:如果系统的其他部分应该围绕相同的资源进行序列化,它们必须都尝试锁定相同的共享储物柜对象。

关于c# - 锁能开多深?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1258889/

相关文章:

c# - 检测 PowerPoint 幻灯片是否隐藏

c# - 如何通过 iPhone/iPad 检测 css 样式

c# - NServiceBus Ninject 在使用 ToMethod 时找不到 NinjectObjectBuilder 范围

C# 与基于列表的属性相等

.net - 如何从 ASP.NET Core 引用 .NET 框架

c - 轮询锁是实现关键部分的正确方法吗?

C# 遍历 DataGridView 并更改行颜色

C# 键盘映射

c - pthread_mutex_t 位于结构体内部并在访问时锁定该结构体

java - 偏向锁定设计决策