boost c++ lock-free queue vs shared queue


Я довольно новичок в многопоточном программировании,я просто знаю самую распространенную очередь производитель-потребитель. Я использую библиотеки boost c++ , и я не знаю, лучше ли использовать boost:: lockfree:: queue или класс-оболочку вокруг std:: queue, который использует 'mutex` и' condition_variable`.

Где лучше использовать свободные от блокировки структуры данных и где лучше использовать простую реализацию, основанную на` mutex `и`condition_variables'?

4 10

4 ответа:

Попробуйте оба варианта в своем приложении, посмотрите, какой из них работает лучше.

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

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

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

Как уже намекали комментаторы, неблокирующая очередь-очень плохая идея для однопроцессорных систем.

(дополнение)

Начиная с 1.54, вы должны знать о некоторых требованиях

boost::lockfree::queue

  • T должен иметь конструктор копирования
  • T должен иметь тривиальный оператор присваивания
  • T должен иметь тривиальный деструктор

boost::lockfree::stack

  • T должен иметь конструктор копирования

boost::lockfree::spsc_queue

  • T должен иметь конструктор по умолчанию
  • T должен быть копируемым

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

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

Решение сводится к постановке вопроса: "будет ли конфликт блокировок проблемой для решаемой задачи?"

Блокировка в параллельной среде решает две различные проблемы

  • корректность: убедитесь, что код действительно выполняет то, что задумано. Предотвратите помехи от других потоков.
  • Пропускная способность / масштабируемость: обеспечивает устойчивый высокий "поток" параллельных операций, проходящих через систему. Позволяют масштабировать производительность системы путем добавление дополнительных ресурсов.
Эти две проблемы являются антагонистическими целями. Классический подходзаключается в защите общей структуры данных с помощью глобальных блокировок. Это гарантирует 100% корректность, но предотвращает масштабирование производительности и особенно уровня параллелизма выше определенной степени, так как общие блокировки приводят к"перегрузке трафика"

Кстати, вы должны быть осторожны при использовании термина "lock free". Строго говоря, сотрудничество операции никогда не могут быть на 100% свободными от блокировки. Но можно организовать сотрудничество умно, так чтобы уменьшить влияние блокировки на тех партнеров, которым действительно нужно получить доступ к одному и тому же элементу одновременно.