зачем нужны токены блокировки для многопоточных программ - PullRequest
0 голосов
/ 26 июня 2019

Ниже приведен пример

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

но я до сих пор не понимаю понятия токена потока, зачем это нужно? является токеном потока то же самое, что семафор в C? Но для программ на Си семафор - это целое число?

1 Ответ

0 голосов
/ 26 июня 2019

lock является мьютексом и работает как POSIX pthread_mutex_lock и pthread_mutex_unlock в C.

Только один фрагмент кода может получить блокировку для данного объекта одновременно, поэтомуспособ синхронизации потоков (не обязательно лучший способ, но это гораздо более подробный и контекстуальный ответ).


Например, следующий код запускает пару потоков одновременно:

  • один увеличивает каждый элемент массива чисел на 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 56 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

Фактической координации между этими двумя задачами нет, поэтому набор, который вы получаете (увеличивается или нет), зависит только от того, какой из них получит блокировку первым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...