Нет абсолютно нет гарантии, что "x - x + 1"
будет компилироваться в инструкции, безопасные для прерываний, на любой платформе, включая x86. Вполне может быть, что это безопасно для конкретного компилятора и конкретной архитектуры процессора, но это вообще не обязательно в стандартах, и стандарт - единственная гарантия, которую вы получаете.
Вы не можете считать что-либо безопасным, основываясь на том, во что, по вашему мнению, оно будет скомпилировано. Даже если конкретный компилятор/архитектура утверждает, что это так, полагаться на него очень плохо, поскольку это снижает переносимость. Другие компиляторы, архитектуры или даже более поздние версии того же компилятора и архитектуры могут довольно легко сломать ваш код.
Вполне возможно, что x = x + 1
может скомпилироваться в произвольную последовательность, например:
load r0,[x] ; load memory into reg 0
incr r0 ; increment reg 0
stor [x],r0 ; store reg 0 back to memory
на ЦП, который не имеет инструкций по увеличению памяти. Или он может быть умным и скомпилировать его в:
lock ; disable task switching (interrupts)
load r0,[x] ; load memory into reg 0
incr r0 ; increment reg 0
stor [x],r0 ; store reg 0 back to memory
unlock ; enable task switching (interrupts)
где lock
отключает, а unlock
разрешает прерывания. Но даже в этом случае это может быть не потокобезопасным в архитектуре, в которой более одного из этих ЦП совместно используют память (lock
может отключать прерывания только для одного ЦП), как вы уже заявили.
Сам язык (или библиотеки для него, если он не встроен в язык) предоставит потокобезопасные конструкции, и вам следует использовать их, а не зависеть от вашего понимания (или, возможно, непонимания) того, какой машинный код будет сгенерирован.
Такие вещи, как Java synchronized
и pthread_mutex_lock()
(доступные для C под некоторыми ОС), - это то, что вам нужно изучить.
person
paxdiablo
schedule
18.09.2009