Пример асинхронного сервера grpc c ++, нужен ли мьютекс в состоянии обработки? - PullRequest
0 голосов
/ 06 ноября 2019

Пример grpc c ++ содержит следующий комментарий:

// Spawn a new CallData instance to serve new clients while we process
// the one for this CallData. 

Я немного озадачен предложением, так как кажется, что новый экземпляр CallData потенциально может служить другомуклиент одновременно. (Это цикл событий?)

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

Например, если код в примере был изменен на приведенный ниже, нужен ли мне мьютекс?

...
else if (status_ == PROCESS) {
        // Spawn a new CallData instance to serve new clients while we process
        // the one for this CallData. The instance will deallocate itself as
        // part of its FINISH state.
        new CallData(service_, cq_);

        // Do I need a mutex here?
        // mutex.lock()
        service->do_something_to_variable();
        // mutex.unlock()

        std::string prefix("Hello ");
        reply_.set_message(prefix + request_.name());

1 Ответ

1 голос
/ 07 ноября 2019

Я постараюсь ответить на каждый из ваших вопросов.

Я немного озадачен предложением, так как кажется, что новый экземпляр CallData> может потенциально обслуживать другого клиента одновременно. (Это событие> цикл?)

Цикл событий здесь представляет собой цикл над cq _-> Next () в HandleRpcs (). Создание новой CallData начинает процесс для обслуживания другого клиента (вы можете увидеть в его конструкторе, что он вызывает службу _-> RequestSayHello, которая позволяет системе обрабатывать другой входящий RPC). Как только это вызывается, события, касающиеся нового входящего RPC, добавляются в очередь завершения. Если предыдущий rpc еще не закончил, события для этого rpc будут добавлены в очередь завершения. Это означает, что мы используем новые CallData для обработки нового rpc одновременно с использованием старого CallData для обработки предыдущего rpc.

Правильно ли я предположить, что не созданы новые потоки и нет общих переменныхчто CallData может действовать, не нужно мьютекс? Или необходим мьютекс?

Правильно, поэтому в этом примере не создаются новые потоки. Единственный поток, который действует, это тот, который выполняет HandleRpcs (). Поэтому, когда я говорю об «одновременном» в ответе выше, это относится к нескольким текущим rpcs-компонентам в любое время (каждый со своими собственными CallData), но на самом деле обработка не является параллельной, потому что в примере приложения есть только один поток. Теперь, если на изображении было несколько потоков, мьютекс для защиты состояния CallData может быть хорошей идеей (в зависимости от того, может ли быть общий доступ к состоянию).

Например, если код впример был изменен на приведенный ниже, нужен ли мне мьютекс?

Если то, что вы написали, было единственным изменением в коде, нет, вам не понадобится мьютекс (и яне знаю, какой метод вы пытаетесь вызвать на service_)

...