-
Помню было обсуждение, а чем кончилось забыл. Вопрос простой: Может ли статься так, что в коде:
if Flag then
DoSmth;
в {1} Flag будет False, а в {2} уже True? На много ядерной(процессорной) машине.
-
Канэчна может. И даж на одноядерной. А причем тут атомарность?
-
> И даж на одноядерной. А причем тут атомарность?
То есть может быть такая ситуация: if Flag then
DoSmth; ? И как бороться? Делать синхронизацию?
-
> И как бороться? Делать синхронизацию?
Естественно. Доступ к данным из потоков всегда надо семафорить. Или сообщения главному потоку постить, чтобы он там семафорил.
-
Ясно, что-то я думал, что в случае с проверкой об этом думать не надо.
-
> Может ли статься так, что в коде: > > if Flag then {1} > DoSmth; {2} > > в {1} Flag будет False, а в {2} уже True?
Нет, не может. Если в {1} Flag будет False, то {2} уже не выполнится.
Может быть, что в {1} Flag будет True, а к моменту выполнения {2} он уже будет False.
> И как бороться? Делать синхронизацию?
Зависит от того, что происходит в DoSmth. В общем случае -- делать.
-
> Kolan © (02.06.08 16:59)
Присвоение, что Boolean, что BOOL - атомарное.
-- Regards, LVT.
-
> Нет, не может.
Ладно, а так: if Flag then
Break;
DoSmth; {<--— Получается что поток 1 проверил флаг, но эта проверка уже не правильная.}
-
> Break; {<--— Поток 2 устанавливает Flag > в True}DoSmth; {<--— Получается что поток 1 проверил > флаг, но эта проверка уже не правильная.}
DoSmth выполняться начнёт по правильному, но вот закончит ли ? А так логика неправильная. Потоки легче воспринимать, как независимые объекты изредка получающие / принимающие данные в основной поток. И смысл из применять только понимая что ограничить поток данных в поток и из него - ключевой момент, особенно на многопроцессорных системах, где из-за этого можно получить нихилую потерю производительности ( AMD с её nUMA не всчёт).
-
> Присвоение, что Boolean, что BOOL - атомарное.
Я думаю, это зависит в общем случае от компилятора. В Delphi атомарное, а вот скажем, в SuperPuperFreePascal не обязательно.
-
не надо присвоение с проверкой путать - это две операции :)
-
могу сказать, что в общем плане очень развивает код из TMultiReadExclusiveWriteSynchronizer
они там имитируют TLS (thread local storage).
посмотри, многое моймешь... и не имхо.
вернее почти ничего, скорее всего, не поймешь, но поймешь, что ты лошок в НАСТОЯЩЕМ многопоточном программировании, как и многие другие (я в том числе).
-
А какая разница, будет он уже true или false? Если при изменениии флага рушится что нибудь, к чему получает доступ код после условия, то он в любом случае должен быть выполнен непрерывно вместе с условием. А иначе разница в десятках миллесекунд значения не имеет (в Windows)
-
> то он в любом случае должен быть выполнен непрерывно вместе > с условием.
В смысле надо обеспечить непрерывное выполнение.
-
-
> Kolan © (02.06.08 18:21) [7] > > Нет, не может. > > Ладно, а так: > if Flag then {<--— Поток 1 проверяет Flag и он False} > Break; > {<--— Поток 2 устанавливает Flag в True} > DoSmth; {<--— Получается что поток 1 проверил флаг, > но эта проверка уже не правильная.}
Это не очень удачный пример. Поскольку здесь явно отсутствует необходимая синхронизация. Более удачный пример сбоя на многопроцессорной машине можешь найти в MSDN Synchronization and Multiprocessor Issuesint iValue;
BOOL fValueHasBeenComputed = FALSE;
extern int ComputeValue();
void CacheComputedValue()
}
BOOL FetchComputedValue(int *piResult)
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.
|