簡體   English   中英

為什么多線程程序需要鎖定令牌

[英]why lock tokens are needed for multithreading programs

下面是一個例子

public class Printer
{
    // Lock token.
    private object threadLock = new object();
    public void PrintNumbers()
    {
       // Use the lock token.
       lock (threadLock)
       {
           ...
       }
    }
}

但是我仍然不知道線程令牌的概念,為什么有必要? 線程令牌與C中的信號量是一樣的嗎? 但是對於C程序,信號量只是整數嗎?

lock是一個互斥鎖,其作用類似於C語言中的POSIX pthread_mutex_lockpthread_mutex_unlock

一次只允許一段代碼獲取給定對象的鎖,因此這是一種同步線程的方式(不一定是最佳方式,但這是一種更為詳盡且高度上下文相關的答案)。


例如,以下代碼可同時運行多個線程:

  • 一個將數字數組的每個元素加10,
  • 另一個打印數組的內容
var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Task.WhenAll(
  Task.Run(() =>
  {
    for (var i = 0; i < 10; i++)
    {
      numbers[i] += 10;
      Thread.Sleep(10);
    }
  }),
  Task.Run(() =>
  {
    foreach (var i in numbers)
    {
      Console.Write(i + " ");
      Thread.Sleep(10);
    }
  })
);

由於它們同時運行,因此輸出類似於:

11 2 13 4 5 6 7 18 9 10

有些數字是遞增的,有些數字不是,並且每次都不同。

但是,循環包含在鎖中的相同代碼:

object threadLock = new object();
var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Task.WhenAll(
  Task.Run(() =>
  {
    lock (threadLock)
    {
      for (var i = 0; i < 10; i++)
      {
        numbers[i] += 10;
        Thread.Sleep(10);
      }
    }
  }),
  Task.Run(() =>
  {
    lock (threadLock)
    {
      foreach (var i in numbers)
      {
        Console.Write(i + " ");
        Thread.Sleep(10);
      }
    }
  })
);

這僅輸出兩件事之一,具體取決於哪個循環首先獲取鎖:

11 12 13 14 15 16 17 18 19 20

要么

1 2 3 4 5 6 7 8 9 10

這兩個任務之間沒有實際的協調,因此您獲得(遞增或不遞增)哪個設置僅取決於哪個首先獲得了鎖定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM