Чтобы обойтись без блокировки, вы должны использовать std::vector<atomic_flag_wrapper>
, где atomic_flag_wrapper
обертывает std::atomic_flag
аналогично коду в этом ответе .
With std::vector<bool>
вы должны использовать блокировку , стандарт явно говорит вам об этом:
Несмотря на [res.on.data.races], необходимы реализации, чтобы избежать гонки данных, когда содержимое объекты, содержащиеся в разных элементах одного контейнера, за исключением vector<bool>
, изменяются одновременно.
http://eel.is/c++draft/container.requirements.dataraces#2 (черновик C ++, 02.08.2020), курсив у меня
На простом английском языке sh:
std::vector<bool>
не требует не нужно убедиться, что запись в два разных элемента не требует гонки; следовательно, может возникнуть гонка за данными; поэтому вам нужна блокировка.
Если бы это был, например, std::vector<char>
, то стандарт гарантирует, что charVector[0]
и charVector[1]
могут быть записаны одновременно. Но все же вы не можете писать в charVector[0]
одновременно из более чем одного потока; вам необходимо использовать атомикс .
std:atomic<bool>
не гарантируется без блокировки, поэтому вам следует использовать std::atomic_flag
с этой гарантией. Однако вы не можете поместить их в std::vector
, потому что они не могут быть созданы копированием. Для этого вам понадобится оболочка, как описано в этом ответе .