Конференция "Основная" » Так присвоение булевой переменной атомарное или нет?
 
  • Kolan © (02.06.08 16:59) [0]
    Помню было обсуждение, а чем кончилось забыл.

    Вопрос простой:
    Может ли статься так, что в коде:

    if Flag then {1}
     DoSmth;    {2}


    в {1} Flag будет False, а в {2} уже True? На много ядерной(процессорной) машине.
  • ага0 (02.06.08 17:05) [1]
    Канэчна может. И даж на одноядерной. А причем тут атомарность?
  • Kolan © (02.06.08 17:21) [2]
    > И даж на одноядерной. А причем тут атомарность?

    То есть может быть такая ситуация:
    if Flag then {<--&#151; Поток 1 проверяет Flag и он False}
                {<--&#151; Поток 2 устанавливает Flag в True}
     DoSmth;    {<--&#151; Получается что поток 1 проверил флаг, но эта проверка уже не правильная.}


    ?

    И как бороться? Делать синхронизацию?
  • tesseract © (02.06.08 17:59) [3]

    > И как бороться? Делать синхронизацию?


    Естественно. Доступ к данным из потоков всегда надо семафорить. Или сообщения главному потоку постить, чтобы он там семафорил.
  • Kolan © (02.06.08 18:09) [4]
    Ясно, что-то я думал, что в случае с проверкой об этом думать не надо.
  • DiamondShark © (02.06.08 18:14) [5]

    > Может ли статься так, что в коде:
    >
    > if Flag then {1}
    >  DoSmth;    {2}
    >
    > в {1} Flag будет False, а в {2} уже True?

    Нет, не может.
    Если в {1} Flag будет False, то {2} уже не выполнится.

    Может быть, что в {1} Flag будет True, а к моменту выполнения {2} он уже будет False.


    > И как бороться? Делать синхронизацию?

    Зависит от того, что происходит в DoSmth.
    В общем случае -- делать.
  • Leonid Troyanovsky © (02.06.08 18:19) [6]

    > Kolan ©   (02.06.08 16:59)  

    Присвоение, что Boolean, что BOOL - атомарное.

    --
    Regards, LVT.
  • Kolan © (02.06.08 18:21) [7]
    > Нет, не может.

    Ладно, а так:
    if Flag then {<--— Поток 1 проверяет Flag и он False}
     Break;
                      {<--— Поток 2 устанавливает Flag в True}
    DoSmth;

        {<--— Получается что поток 1 проверил флаг, но эта проверка уже не правильная.}
  • tesseract © (02.06.08 20:36) [8]

    >  Break;                   {<--— Поток 2 устанавливает Flag
    > в True}DoSmth;     {<--— Получается что поток 1 проверил
    > флаг, но эта проверка уже не правильная.}


    DoSmth выполняться начнёт по правильному, но вот закончит ли ? А так логика неправильная. Потоки легче воспринимать, как независимые объекты изредка получающие / принимающие данные в основной поток.  И смысл из применять только понимая что ограничить поток данных в поток и из него - ключевой момент, особенно на многопроцессорных системах, где из-за этого можно получить нихилую потерю производительности ( AMD с её nUMA не всчёт).
  • DVM © (02.06.08 22:35) [9]

    > Присвоение, что Boolean, что BOOL - атомарное.

    Я думаю, это зависит в общем случае от компилятора. В Delphi атомарное, а вот скажем, в SuperPuperFreePascal не обязательно.
  • Игорь Шевченко © (02.06.08 22:46) [10]
    не надо присвоение с проверкой путать - это две операции :)
  • Тимохов (03.06.08 01:58) [11]
    могу сказать, что в общем плане очень развивает код из TMultiReadExclusiveWriteSynchronizer

    они там имитируют TLS (thread local storage).

    посмотри, многое моймешь... и не имхо.

    вернее почти ничего, скорее всего, не поймешь, но поймешь, что ты лошок в НАСТОЯЩЕМ многопоточном программировании, как и многие другие (я в том числе).
  • Рамиль © (03.06.08 10:01) [12]
    А какая разница, будет он уже true или false? Если при изменениии флага рушится что нибудь, к чему получает доступ код после условия, то он в любом случае должен быть выполнен непрерывно вместе с условием.
    А иначе разница в десятках миллесекунд значения не имеет (в Windows)
  • Рамиль © (03.06.08 10:02) [13]

    > то он в любом случае должен быть выполнен непрерывно вместе
    > с условием.

    В смысле надо обеспечить непрерывное выполнение.
  • Leonid Troyanovsky © (03.06.08 18:10) [14]

    > Kolan ©   (02.06.08 18:21) [7]

    http://msdn.microsoft.com/en-us/magazine/cc302329.aspx

    --
    Regards, LVT.
  • oxffff © (03.06.08 21:45) [15]

    > Kolan ©   (02.06.08 18:21) [7]
    > > Нет, не может.
    >
    > Ладно, а так:
    > if Flag then {<--— Поток 1 проверяет Flag и он False}
    >  Break;
    >                   {<--— Поток 2 устанавливает Flag в True}
    > DoSmth;     {<--— Получается что поток 1 проверил флаг,
    > но эта проверка уже не правильная.}


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

    Более удачный пример сбоя на многопроцессорной машине можешь найти в MSDN Synchronization and Multiprocessor Issues

    int iValue;
    BOOL fValueHasBeenComputed = FALSE;
    extern int ComputeValue();

    void CacheComputedValue()
    {
     if (!fValueHasBeenComputed)
     {
       iValue = ComputeValue();
       fValueHasBeenComputed = TRUE;
     }

    }

    BOOL FetchComputedValue(int *piResult)
    {
     if (fValueHasBeenComputed)
     {
       *piResult = iValue;
       return TRUE;
     }

     else
       return FALSE;
    }



    There is a race condition in this code on multiprocessor systems because the processor that executes CacheComputedValue the first time may write fValueHasBeenComputed to main memory before writing iValue to main memory. Consequently, a second processor executing FetchComputedValue at the same time reads fValueHasBeenComputed as TRUE, but the new value of iValue is still in the first processor's cache and has not been written to memory.
 
Конференция "Основная" » Так присвоение булевой переменной атомарное или нет?
Есть новые Нет новых   [134491   +8][b:0][p:0.001]