Правильность вашего шаблона взаимного исключения зависит от назначения _flag = false, являющегося атомарным. Представьте, что произойдет, если назначение может быть прервано другим потоком. Если промежуточные результаты присваивания могут быть интерпретированы как ложные при тестировании, одно назначение может привести к тому, что несколько потоков войдут в критический раздел.
Правильность шаблона взаимного исключения также зависит от отсутствия оптимизаций в компиляторе, которые могут изменить порядок инструкций. Представьте себе «умный» компилятор, который переместил бы присваивание _flag = false up, потому что _flag не упоминается в коде, который находится между ними (и код между ними не генерирует исключения). Компилятор может затем оптимизировать часть в секции замка читать
if(_flag) return;
Оба примера, почему шаблон может не являются весьма спекулятивными, и я думаю, что вы в безопасности в предположении, что работает. Однако при наличии другого варианта, который работает по мере необходимости, вам лучше использовать его (см. Другие сообщения). Если в одном коде есть другие разработчики, им не нужно учитывать, работает ли шаблон.
Это нормально, я буду использовать TryEnter, но можете ли вы объяснить, как это небезопасно? Благодарю. – marijne
Ну, вы получаете доступ к знаку за пределами замка. Как это бывает, вы устанавливаете только значение false, но это означает, что вы можете отрицать существенный поток - я могу предвидеть проблемы. Так как относительно просто использовать TryEnter, я бы использовал это ... –