使用互锁用法

kik*_*iki 4 c# multithreading

我正在尝试编写一个多线程程序,其中每个线程将使用一个计数器,然后递增它.

例如:

lock(this)
{
   counter++;
   Console.WriteLine(counter); 
}
Run Code Online (Sandbox Code Playgroud)

我知道,对于增量我可以使用:

System.Threading.Interlocked.Increment(counter);
Run Code Online (Sandbox Code Playgroud)

但是如果锁定增量和对计数器做某事呢?

谢谢!

Bra*_*vic 25

这样做没问题:

线程A:

var incremented_counter = Interlocked.Increment(ref counter);
Console.WriteLine(incremented_counter);
Run Code Online (Sandbox Code Playgroud)

线程B:

Interlocked.Increment(ref counter);
Run Code Online (Sandbox Code Playgroud)

这样做是可以的:

线程A:

lock (the_lock) {
   ++counter;
   Console.WriteLine(counter); 
}
Run Code Online (Sandbox Code Playgroud)

线程B:

lock (the_lock) {
   ++counter;
}
Run Code Online (Sandbox Code Playgroud)

这样做可以但多余:

线程A:

lock (the_lock) {
    var incremented_counter = Interlocked.Increment(ref counter);
    Console.WriteLine(incremented_counter);
}
Run Code Online (Sandbox Code Playgroud)

线程B:

lock (the_lock) {
    Interlocked.Increment(ref counter);
}
Run Code Online (Sandbox Code Playgroud)

但这样做并不行:

线程A:

Interlocked.Increment(ref counter);
Console.WriteLine(counter);
Run Code Online (Sandbox Code Playgroud)

线程B:

Interlocked.Increment(ref counter);
Run Code Online (Sandbox Code Playgroud)

它也不是这样做的:

线程A:

lock (the_lock) {
   ++counter;
   Console.WriteLine(counter); 
}
Run Code Online (Sandbox Code Playgroud)

线程B:

Interlocked.Increment(ref counter);
Run Code Online (Sandbox Code Playgroud)

它也不是这样做的:

线程A:

var incremented_counter = Interlocked.Increment(ref counter);
Console.WriteLine(incremented_counter);
Run Code Online (Sandbox Code Playgroud)

线程B:

lock (the_lock) {
   ++counter;
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,不要使用lockthis.)

  • 是的,但我投票的另一个原因是因为你只是举例,说明做什么和不做什么,而不告诉他们*为什么*这是对还是错.不要误解我的意思,你的例子不仅仅是正确的.但是这样的事情:`var incremented_counter = Interlocked.Increment(ref counter);`可能意味着某人不知道它做了什么,计数器没有增加,只有`incremented_counter`已经递增.但我会向你投票:P (4认同)

Sco*_*ain 5

所有 Interlock 函数都会在修改后返回值的副本,并在线程期间使用该返回值。

var localCounter = System.Threading.Interlock.Increment(counter);
Run Code Online (Sandbox Code Playgroud)

  • `Interlocked.Exchange` 和 `Interlocked.CompareExchange` 返回修改前的值(如果它们返回“修改后”的值,它们将毫无用处)。 (2认同)

Ste*_*ven 1

您需要使用锁来保护读取和写入。在这种情况下,该lock语句效果最好,并且最容易遵循:

private int counter;
private readonly object locker = new object();

public void IncrementCounter()
{
    lock (this.locker)
    {
       this.counter++;
       Console.WriteLine(counter); 
    }
}

public int GetCounter()
{
    lock (this.locker)
    {
       return this.counter;
    }
}
Run Code Online (Sandbox Code Playgroud)