C #: что происходит, когда два потока пытаются прочитать и записать одно и то же поле одновременно, предполагая, что поле меньше или равно 32 битам - PullRequest
0 голосов
/ 22 октября 2018

Согласно книге Джо Албахари Потоки в C # чтение и запись поля размером менее или равным 32 битам является атомарной операцией: это подразумевает, что в такойВ сценарии невозможно, чтобы разорванное чтение ( здесь , вы можете найти простой способ воспроизвести разорванное чтение, используя десятичное поле).

Учитывая это, рассмотрим следующее консольное приложение C #:

using System;
using System.Threading;

namespace ConsoleApp2
{
  class Program
  {
    static void Main(string[] args)
    {
      var obj = new Test();
      var random = new Random();

      var thread1 = new Thread(() =>
      {
        while (true)
        {
          Console.WriteLine($"The boolean value is {obj.field}");
        }
      });

      var thread2 = new Thread(() =>
      {
        while (true)
        {
          obj.field = (random.Next() % 2) == 0;
        }
      });

      thread1.Start();
      thread2.Start();
    }
  }

  class Test
  {
    public bool field;
  }
}

Мой вопрос: когда я запускаю такую ​​программу, что именно происходит в адресе памяти, содержащем значение поля, являющегосязаписано и прочитано одновременно двумя потоками?Можно ли искажать его значение, делая это?

Исходя из моего понимания, существует одновременный доступ к одному и тому же адресу памяти в одно и то же время:

  1. Могу ли я получить любой видисключение во время выполнения делает это?
  2. способен ли базовый процессор справиться с таким сценарием без ошибок?

Если поставить вопрос более общим образом: когда два потока одновременно читают и записывают 32-битное значение единственная возможная проблема заключается в том, что нет гарантии на считываемое значение (я имею в виду, что считываемое значение является полностью неопределенным из-за одновременной операции записи)?

1 Ответ

0 голосов
/ 22 октября 2018

1.может ли я получить какое-либо исключение во время выполнения?

Нет.Современные процессоры имеют способ блокировать другие ядра для монопольного доступа (записи) по тому же адресу, что и спин-блокировка.(фактическая реализация зависит от процессора)

2. способен ли базовый процессор справиться с таким сценарием без ошибок?

Да, все выровненные 4-байтовые записи (или 8-байтовые для 64-битной ОС) гарантированно являются атомарными в том смысле, что вы не можете получить поврежденные данные (2 байта из core1 и 2 байта из core2).Однако, если запись> 8 байт или выходит за пределы выровненной границы (например, большое целое число), вы можете попасть в поврежденную память, если это было сделано без блокировки.

Ofc всегда есть шанс, что реализация процессора испортится, и в этом случае вы SOL

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