Поведение метода/глобальных переменных внутри критической секции с использованием класса Mutex

Я читаю книгу о C #, я знаю, для чего используется критический раздел, однако этот пример был в книге, и это меня смущает:

public bool BankTransferWithMutex(int amount)
{
    bool result = false;

    MyMutex.WaitOne();

    if (Balance >= amount)
    {
        Balance -= amount;
        result = true;
    }

    MyMutex.ReleaseMutex();
    //My question is here..
    return result;
    }
}

Мой вопрос заключается в следующем: представьте, что было два потока, один из которых получил доступ к мьютексу, и банковский перевод успешно установил переменную результата в значение true.. если появился другой поток (до того, как первый вернет и введет этот метод он сразу поставил бы результат = ложь. Будет ли первый поток иметь переменную результата, измененную и, следовательно, вернувшую бы ложь, несмотря на успешный банковский перевод? Делая состояние объекта несогласованным??

Спасибо за уделенное время :)


person DavidN    schedule 31.01.2015    source источник
comment
result — это локальная переменная, а не общая. Скажите, какую книгу вы читаете? Я предлагаю вам прочитать другую книгу.   -  person Hamlet Hakobyan    schedule 31.01.2015
comment
Результатом является локальная переменная без какой-либо ссылки, указателя или чего-то еще вне вашей функции. Он не может быть изменен другим потоком.   -  person Adriano Repetti    schedule 31.01.2015
comment
Но мьютекс существует из-за переменной Balance, а это общая переменная, верно?   -  person DavidN    schedule 31.01.2015
comment
Вы не показали код, определяющий Баланс, поэтому мы не знаем, является ли он общим, но предположительно да, иначе пример не имеет смысла. Кстати, пример странен тем, что в нем аргумент BankAccount не используется. Или вы не весь пример выложили?   -  person RenniePet    schedule 31.01.2015
comment
Что касается результата переменной, вы должны принять во внимание, что это локальная переменная, поэтому результат есть для каждого вызова BankTransferWithMutex(). Если есть 10 потоков, и все они находятся в BankTransferWithMutex() одновременно, то имеется 10 различных переменных результата.   -  person RenniePet    schedule 31.01.2015
comment
Аргумента не должно быть... извините :/ Я собираюсь его отредактировать. Баланс определяется как глобальная переменная, например: class BankAccount { int Balance; ... Но что определяет общую переменную? Я думал, что это просто переменная, к которой могут иметь доступ два потока, но это сделало бы результат также общим, чего на самом деле нет.   -  person DavidN    schedule 31.01.2015
comment
Хммм, я понимаю, почему я все понял неправильно, большое спасибо за помощь!   -  person DavidN    schedule 31.01.2015


Ответы (1)


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

Предполагая, что код, на который вы смотрите, несколько похож на этот:

   public class BankAccount
   {
      private int Balance;

      private Mutex MyMutex = new Mutex();


      public bool BankTransferWithMutex(int amount)
      {
         bool result = false;

         MyMutex.WaitOne();

         if (Balance >= amount)
         {
            Balance -= amount;
            result = true;
         }

         MyMutex.ReleaseMutex();
         //My question is here..
         return result;
      }
   }

тогда фундаментальное различие между Balance и result заключается в том, что Balance является переменной экземпляра класса, и существует один экземпляр его для каждого экземпляра класса BankAccount. При этом result является локальной переменной, поэтому существует один экземпляр result для каждого существующего (обычно нулевого) вызова метода BankTransferWithMutex().

Таким образом, если есть один экземпляр объекта BankAccount, и он совместно используется 10 потоками, то 10 потоков совместно используют один экземпляр Balance. Переменные result связаны с вызовами метода BankTransferWithMutex(), поэтому для каждого текущего вызова существует одна переменная — обычно ноль, но может быть до 10.

Вот ссылка MSDN, хотя для того, чтобы увидеть все это, нужно щелкнуть кучу подтем: https://msdn.microsoft.com/en-us/library/aa691160%28v=vs.71%29.aspx

person RenniePet    schedule 31.01.2015