究竟什么"锁定"锁定?

Thi*_*Use 0 c# multithreading locking

我正在创建一个创建和管理多个套接字连接的类,它将从套接字接收的信息转发到主线程,反之亦然.我传递了大量信息的多线程对我来说是新的(就像C#中的大多数事情一样),所以我需要澄清究竟locks做了什么.

当我锁定方法的一部分时,它只确保没有其他线程可以进入该部分代码,或者它是否确实阻止该部分代码中的所有变量被其他线程修改,无论它们出现在何处?

例如:

public class TestLock
{
    public volatile int a = 0;
    public volatile int b = 2;
    private object ALock = new Object();

    public TestLock() { }

    public void UnlockEdit(int atemp, int btemp)
    {
        a = atemp;
        b = btemp;
    }

    public void LockedEdit(int atemp, int btemp)
    {


        lock(ALock)
        {
            a = atemp;
            b = btemp;
        }
    }

    public int[] ReturnValues()
    {
        int[] ret = new int[2];

        lock (ALock)
        {
            ret[0] = a;
            ret[1] = b;
        }

        return ret;
    }

}
Run Code Online (Sandbox Code Playgroud)

如果线程A调用该LockedEdit方法并在线程B进入之前稍微到达锁定UnlockEdit.怎么了?该锁将防止螺纹的修改ab?它会阻止吗?或者锁只适用于一个特定的代码分支?或者我应该将相同的lockobject(ALock)应用于我想要修改和从多个线程读取的对象的每个读取和写入方法?

Eri*_*ert 7

当我锁定方法的一部分时,它只确保没有其他线程可以进入该部分代码,或者它是否确实阻止该部分代码中的所有变量被其他线程修改,无论它们出现在何处?

这个问题是如此复杂和不完整,以至于无法回答.我们重写一下吧.

当我锁定一个方法的一部分时,它确保没有其他线程可以进入该部分代码吗?

是.然而,更准确的说明方式是:在获得与给予该lock语句的"monitor"对象相关联的锁之前,不能输入锁定的部分.该锁定只能由一个线程一次获得.

我还注意到,在涉及监视器的更高级用法的场景中如何获得锁定存在微妙之处,例如脉冲.再次,请仔细阅读文档,以获取有关监视器操作的确切语义的说明.

当我锁定一个方法的一部分时,它只确保没有其他线程可以进入该部分代码吗?

不能.采取锁定还有其他行动,而不仅仅是确保阻止相互排斥.例如,它引入了一个内存屏障.

它实际上是否阻止该部分代码中的所有变量被其他线程修改,无论它们出现在何处?

当然不是!

锁会阻止线程B修改a和b吗?

你建造了一个带有门的浴室,一侧有一把锁,另一侧有一扇通向外面的世界.你锁上卫生间的门.这似乎是一种有效的方法来确保每次只能挤出一个牙膏吗?

它会阻止吗?

会阻止什么?

锁只适用于一个特定的代码分支吗?

我无法理解这个问题.

我应该将相同的"锁定"对象(ALock)应用于我想要修改和从多个线程读取的对象的每个读取和写入方法吗?

是.

你没有问过的问题但是应该有:

我应该首先使用共享内存多线程吗?

可能不是.即使是专家也很难做到这一点.如果我正在进行套接字编程,我首先使用async-await或任务并行库来管理我的异步,而不是直接参与线程.线程是专门针对专家的低级工具; 尝试提高抽象级别几个级别.