Нужна ли блокировка, если у меня есть EventWaitHandle

Изучение многопоточности из предсердия альбахари. Мне нужен замок _locker в образце ниже? Я полагаю, нет, так как _message защищен EventWaitHandle, Я прав?

class TwoWaySignaling
{
  static EventWaitHandle _ready = new AutoResetEvent (false);
  static EventWaitHandle _go = new AutoResetEvent (false);
  static readonly object _locker = new object();
  static string _message;

  static void Main()
  {
    new Thread (Work).Start();

    _ready.WaitOne();                  // First wait until worker is ready
    lock (_locker) _message = "ooo";
    _go.Set();                         // Tell worker to go

    _ready.WaitOne();
    lock (_locker) _message = "ahhh";  // Give the worker another message
    _go.Set();
    _ready.WaitOne();
    lock (_locker) _message = null;    // Signal the worker to exit
    _go.Set();
  }

  static void Work()
  {
    while (true)
    {
      _ready.Set();                          // Indicate that we're ready
      _go.WaitOne();                         // Wait to be kicked off...
      lock (_locker)
      {
        if (_message == null) return;        // Gracefully exit
        Console.WriteLine (_message);
      }
    }
  }
}

2 ответа

Решение

Ты прав.

Такие проблемы не могут быть просто проверены методом проб и ошибок. Их лучше всего анализировать с помощью логического мышления:

  • Какой поток выполняет какой код?
  • Что может произойти в другом потоке прямо сейчас?
  • Что произойдет, если другой поток получит больше процессорного времени? и т.п.

Основной поток будет выполнять код только в Main() и рабочий поток будет выполнять код только в Work(), Это достаточно просто.

Если вы посмотрите, как осуществляется доступ к критическому ресурсу, вы заметите, что доступ к _message в Main() всегда между

_ready.WaitOne();

а также

_go.Set();

тогда как доступ к _message в Work() всегда между

_go.WaitOne();

а также

_ready.Set();

Таким образом, один из потоков всегда будет ждать другого, прежде чем получить доступ _message и замок не нужен.

Вы остановили ваши темы от доступа к _message переменная в то же время. Ваша логика здесь самодостаточна и предсказуема, что не всегда так. иногда вы будете читать из других мест, и поток не будет полностью управляемым, и в этом случае вам нужно будет заблокировать критические переменные.

Другие вопросы по тегам