Пример для иллюстрации многопоточной обработки данных. В качестве produser'а используется функция чтения из /dev/urandom, в качестве consumer'а - функция расчета контрольной суммы по алгоритму Keccak224 Имеет 2 режима работы - синхронный и асинхронный. Синхронный режим добавлен в качестве референсного для сравнения производительности. Он позволяет запустит произволное количество потоков, в которых обработка данных выполняется сразу после их получния. При его использовании можно наблюдать, что кратный прирост производительности происходит только при изменении количества потоков с одного до двух. Дальнейшее увеличении не приводит к значительному росту обработанных байт из-за блокирующего ресурса /dev/urandom.
- std::atomic как признак окончания работы
- std::atomic <size_t> для подсчета обработанных байт
- conditinal variable для своевременного запуска одного потока обработки при получении порции новых данных Для atomic переменных используется модель памяти relaxed, так как более строгая синхронизация для данных задач не требуется.
В текущей версии примера моделируется ситуация, в которой обработка данных выполняется медленее, чем их получение (в функцию consumer'a добавлена задержка в половину секунды. Соответсвенно увеличивая количество потоков обработка можно наблюдать пропорциональное увеличение количества обрабатываемых байт.
ветка ugly_queue Сделана для отладки механизмов синхронизации на основе std::queue, поэтому имеет неустранимый недостаток - блокировка операции записи при выполнении операции чтения. Это приводит к незначительному прогрессу или даже регрессу производительности при увеличении количества потоков produser'ов и consumer'ов в асинхронном режиме. в общем, полный швах.