我有以下代码:
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/