Простая защищенная мьютексом очередь и потокобезопасная очередь в C ++ - PullRequest
0 голосов
/ 17 июня 2020

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

/*Enqueue*/
mutex.lock();
queue.push();
mutex.unlock();

/*Dequeue*/
mutex.lock();
val = queue.front
mutex.unlock();
/*some operation*/
mutex.pop();

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

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Ваша заявка будет ограничена одним главным. Мы называем это узким местом. По моему опыту, 90% приложений, которые я видел, были ограничены пропускной способностью шины, передавая память в / из основной памяти / ЦП.

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

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

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

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

Профиль и проверка.

2 голосов
/ 17 июня 2020

Мьютексы и условные переменные выполняют две разные функции, хотя они часто используются вместе.

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

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

Ваша первая мысль при написании многопоточного кода должна заключаться в написании надежного и безопасного кода. Совершать ошибки очень легко, особенно если вы новичок в этой области, а ошибки очень сложно диагностировать, поскольку они приводят к спорадическим c, непредсказуемым ошибкам. Позаботьтесь о производительности позже.

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