многопоточность — C ++, если один поток записи переключает bool после завершения, безопасно ли читать этот bool в цикле в одном другом потоке?

Я строю очень простую программу в качестве упражнения.

Идея состоит в том, чтобы вычислить общий размер каталога путем рекурсивной итерации по всему его содержимому и суммирования размеров всех файлов, содержащихся в каталоге (и его подкаталогах).

Чтобы показать пользователю, что программа все еще работает, это вычисление выполняется в другом потоке, в то время как основной поток печатает точку . раз в секунду.

Теперь основной поток, конечно, должен знать, когда он должен прекратить печатать точки и может найти результат.
Можно использовать, например, std::atomic<bool> done(false); и передать это потоку, который выполнит вычисление, которое установит его true как только это закончено. Но мне интересно, если в этом простом случае (один поток пишет после завершения, один поток периодически читает до нуля), необходимо ли для этого использовать атомарные типы данных. Очевидно, если множественный потоки могут писать в него, он должен быть защищен. Но в этом случае есть только один поток записи и один поток чтения.

Нужно ли здесь использовать атомарный тип данных или это излишне, и вместо этого можно использовать обычный тип данных?

3

Решение

Да, это необходимо. Правило состоит в том, что если два потока потенциально могут одновременно обращаться к одной и той же памяти, и хотя бы один из потоков является записывающим, то у вас есть гонка данных. Любое выполнение программы с гонкой данных имеет неопределенное поведение.

Соответствующие цитаты из стандарта C ++ 14:

1.10 / 23

Выполнение программы содержит гонку данных, если она содержит два потенциально одновременных конфликтующих действия, по крайней мере одно из которых не является атомарным, и ни одно не происходит раньше другого, за исключением специального случая для обработчиков сигналов, описанных ниже. Любая такая гонка данных приводит к неопределенному поведению.

1.10 / 6

Две оценки выражений конфликтуют, если одна из них изменяет ячейку памяти (1.7), а другая обращается или изменяет ту же ячейку памяти.

2

Другие решения

Да, это необходимо.

Проблема заключается в том, что разные ядра процессора могут иметь разные представления об «одних и тех же» данных, в частности, данных, которые кэшируются в ЦП. atomic part гарантирует, что эти кэши будут правильно очищены, чтобы вы могли безопасно делать то, что пытаетесь сделать.

В противном случае вполне возможно, что другой поток никогда не увидит изменения флага в первом потоке.

3

Да, это необходимо. В противном случае не гарантируется, что изменения в bool в одном потоке будет наблюдаться в другом потоке. На самом деле, если компилятор видит, что bool переменная, по-видимому, никогда больше не используется в потоке выполнения, который ее устанавливает, она может полностью оптимизировать код, который устанавливает значение bool,

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector