многопоточная переменная C / C ++ без кеша (Linux) - PullRequest
1 голос
/ 23 августа 2011

Я использую 2 pthreads, где один поток «уведомляет» другой о событии, и для этого есть переменная (обычное целое число), которая устанавливается вторым потоком.

Это работает, но мой вопрос: возможно ли, что обновление не сразу увидится первым (читающим) потоком, то есть кеш не обновляется напрямую? И если да, есть ли способ предотвратить такое поведение, например, как ключевое слово volatile в Java?

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

/ edit: 2-й вопрос: можно ли принудительно установить, что переменная хранится в кеше ядра, где находится поток 1, поскольку этот читает его все время.

Ответы [ 4 ]

2 голосов
/ 24 августа 2011

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

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

Использование простых int переменных или даже volatile -качественные из них подвержены ошибкам, если только компилятор не гарантирует, что они имеют соответствующую семантику.например, MSVC дает определенные гарантии относительно атомарности и ограничений порядка простых нагрузок и сохраняет в volatile переменные, а gcc - нет.

2 голосов
/ 23 августа 2011

Может быть не сразу видно другим процессорам, но не из-за когерентности кэша.Самые большие проблемы с видимостью будут связаны с схемами выполнения вашего процессора не по порядку вашего процессора или с инструкциями по компиляции вашего компилятора при оптимизации.

Чтобы избежать обеих этих проблем, вы должны использовать память барьеры .Я полагаю, что большинство примитивов pthread являются естественными барьерами памяти, что означает, что вы не должны ожидать, что нагрузки или хранилища будут перемещены за пределы границ, образованных вызовами lock и unlock.Ключевое слово volatile также может быть полезно для отключения определенного класса оптимизаций компилятора, который может быть полезен при выполнении алгоритмов без блокировок, но не заменяет барьеры памяти.

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

2 голосов
/ 23 августа 2011

Мне кажется, что вы должны использовать переменную условия pthread в качестве вашего механизма сигнализации. Это решает все проблемы, которые вы описываете.

1 голос
/ 23 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...