gRP C grpc_completion_queue_next () кажется несправедливым, когда активно несколько потоков - PullRequest
1 голос
/ 12 марта 2020

мой вариант использования

У меня есть сервер с асинхронной c службой, содержащей два разных двунаправленных потоковых RPC (назовите их stream1 и stream2). У меня также есть потоковый клиент asyn c bidir, подключенный к этому серверу. Когда сервер получает чтение на stream1, он отвечает 100000 операций записи клиенту. Когда клиент получает Read on stream1, он сохраняет ответные данные в вектор. У клиента есть сигнал тревоги, запускающий «write_tag» в al oop, когда вектор данных ответа пуст. Когда он не пустой, он извлекает первый элемент из вектора (FIFO) и выполняет запись в поток 2.

Когда сервер получает чтение в потоке 2, он просто отвечает записью.

настройка сервера

stream1 и stream2 имеют свои собственные ServerContexts, но совместно используют очередь завершения. У меня есть только один поток, который опрашивает CQ и обрабатывает тег перед повторным опросом CQ ... (за исключением моего второго решения проблемы). Каждый экземпляр потока живет в своем собственном объекте CallData. Теги - это адрес рассматриваемого объекта CallData.

настройка клиента

stream1 и stream2 используют отдельные ClientContexts, но совместно используют очередь завершения. Он также имеет только один поток, который опрашивает CQ и обрабатывает тег. Здесь тег является перечислением, которое содержит все возможные операции для обоих потоков, теги разделены между потоками с помощью READ_STREAM1 и READ_STREAM2 и т. Д. c ..

моя проблема

Моя проблема заключается в том, что сервер не отвечает клиенту на stream2, пока это не будет сделано Запись на stream1.

Изображение, объясняющее мою проблему (не разрешается публиковать изображения из-за <10 повторений) </a>

решение 1

Если я вводю Тревогу между каждой записью -называет, работает так, как задумано, но с ужасной производительностью. Тот же подход, что и у команды GResearch в статье . Их пример кода: здесь .

решение 2

Другой способ решения этой проблемы - создать специальный поток для получения тегов из CQ с помощью CQ-> next ( ), а затем сохраните теги в очереди, из которой другой поток считывает теги и выполняет соответствующую обработку. Это тоже (из-за плохого выполнения занято-ожидания) выполнено действительно плохо.


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

Надеюсь, я все прояснил.

...