Планировщик!
По сути, если у вас есть несколько процессов, они могут запускаться в любом странном порядке. Если эти процессы совместно используют ресурс, из которого они одновременно читают и пишут (будь то файл, память или какое-либо устройство ввода-вывода), операции будут чередоваться во всевозможных странных порядках. В качестве простого примера, предположим, что у вас есть два потока (они являются потоками, поэтому они совместно используют память), и они оба пытаются увеличить глобальную переменную, x.
y = x + 1;
x = y
Теперь запустите эти процессы, но чередуйте код таким образом
Предположим, х = 1
P1:
y = x + 1
Так что теперь в P1, для переменной y, которая является локальной и находится в стеке, y = 2
. Затем приходит планировщик и запускает P2
P2:
y = x + 1
x = y
x был все еще 1, входящий в это, таким образом, 1 был добавлен к этому и теперь x = 2
Затем P1 заканчивает
P1
x = y
и х по-прежнему 2! Мы увеличили x дважды, но получили только один раз. И поскольку мы не знаем , как это произойдет, это называется недетерминированным поведением.
Хорошая новость заключается в том, что вы наткнулись на одну из самых сложных проблем в системном программировании, а также на основной боевой клич многих людей с функциональными языками.