Оба потока должны использовать либо InterlockedDecrement
/ InterlockedIncrement
, или одного и того же критического раздела. Нет оснований для правильного смешивания и сопоставления.
Рассмотрим следующую последовательность событий:
Thread A: enter the critical section
Thread A: read count into a register
Thread A: increment the value in the register
Thread B: InterlockedDecrement(&count) <<< There's nothing to stop this from happening!
Thread A: write the new count
Thread A: leave the critical section
Чистый результат: вы потеряли декремент!
Полезная (если намеренно упрощенная) ментальная модель для критических секций такова: все, что входит в критическую секцию, - это предотвращает вход других потоков в ту же критическую секцию. Он автоматически не запрещает другим потокам выполнять другие действия, которые могут потребовать синхронизации.
И все, что InterlockedDecrement
делает, это обеспечивает атомарность декремента. Это не мешает любому другому потоку выполнять вычисления на устаревшей копии переменной и затем записывать результат обратно.