Я занимаюсь разработкой системы, которая подключается к одному или нескольким потокам фидов данных и делает некоторый анализ данных, чем триггерные события на основе результата. В типичной многопоточной настройке производителя/потребителя у меня будет несколько потоков производителей, которые помещают данные в очередь, и несколько потребительских потоков, считывающих данные, а потребители интересуются только последней точкой данных плюс n количеством точек. Нити производителя должны будут блокироваться, если медленный потребитель не может идти в ногу, и, конечно, потоки потребителей будут блокироваться, когда нет необработанных обновлений. Использование типичной параллельной очереди с блокировкой чтения/записи будет работать хорошо, но скорость ввода данных может быть огромной, поэтому я хотел уменьшить свои блокирующие накладные расходы, особенно блокировки для производителей. Я думаю, что круговой буфер без блокировки - это то, что мне нужно.
Теперь два вопроса:
-
Является ли круглый буфер без блокировки ответом?
-
Если это так, прежде чем я скачу свой собственный, вы знаете какую-либо публичную реализацию, которая будет соответствовать моей потребности?
Любые указатели на реализацию циклического незакрепленного буфера всегда приветствуются.
BTW, делая это на С++ в Linux.
Дополнительная информация:
Время отклика имеет решающее значение для моей системы. В идеале потребительские потоки захотят увидеть как можно скорее любые обновления, поскольку дополнительная 1 миллисекундная задержка может сделать систему бесполезной или стоит намного меньше.
Идея дизайна, к которой я склоняюсь, представляет собой круглосуточный буфер с замкнутым циклом, в котором потоки производителей помещают данные в буфер так быстро, как можно, позвольте вызывать головку буфера A без блокировки, если только буфер не является полный, когда A встречает конец буфера Z. Потребительские потоки будут содержать два указателя на круговой буфер, P и P n, где P - это локальная головка буфера потока, а P n - n-й элемент после P. Каждый потребительский поток будет продвигать свои P и P n после завершения обработки текущего P, а конец указателя буфера Z продвигается с самым медленным P nсуб > . Когда P улавливает до A, что означает, что больше не требуется новое обновление для обработки, потребитель вращается и занят, ожидая, чтобы A снова продвинулся. Если потребительский поток вращается слишком долго, его можно уложить и ждать переменной условия, но я в порядке с потребителем, занимающим процессорный цикл, ожидающим обновления, потому что это не увеличивает мою задержку (у меня будет больше ядер процессора чем потоки). Представьте, что у вас есть круговой трек, и производитель работает перед кучей потребителей, ключевым моментом является настройка системы, так что производитель обычно работает на несколько шагов впереди потребителей, и большая часть этих операций может быть выполненных с использованием технологий блокировки. Я понимаю, что получить детали прав реализации непросто... хорошо, очень сложно, поэтому я хочу учиться на чужих ошибках, прежде чем сделать несколько своих.