Нужно ли использовать мьютекс для защиты доступа к массиву мьютексов из разных потоков? - PullRequest
1 голос
/ 06 марта 2020

Допустим, у меня есть куча файлов и массив с мьютексом для каждого файла. Теперь у меня есть разные потоки чтения из случайных файлов, но сначала они должны получить блокировку из массива. Должен ли я иметь блокировку на весь массив, который должен быть получен до получения мьютекса для конкретного файла?

Ответы [ 2 ]

2 голосов
/ 06 марта 2020

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

Держите доступ других потоков к памяти вдали от того, что другой человек с потоками.

Ассоциируйте каждый поток с данными, которые плотно упакованы (но выровнены) и содержат как можно меньше строк кэша . Один мьютекс и один набор данных - нигде не близко к тому, где другие рабочие потоки нуждаются в доступе.

Вы можете легко измерить эффект, используя самодельный std::hardware_constructive_interference_size как ... 64 (популярный , не научный c, но общий).

Разделите данные таким образом, чтобы ни одному другому потоку не приходилось касаться данных в этих 64 (или любых других числах) байтов.

Это " без шуток? " опыт.


Число 64 почти произвольно. Я могу скомпилировать программу, используя эту константу - но она не будет переведена во что-то значимое для другой целевой платформы - она ​​останется 64. Это лучшее предположение.

Понимание std :: hardware_destructive_interference_size и станд :: hardware_constructive_interference_size

1 голос
/ 06 марта 2020

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

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

...