grpc c++ example具有以下注释。

// 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());

最佳答案

我将尽力回答您的每个问题。



这里的事件循环是HandleRpcs()中cq _-> Next()的循环。创建一个新的CallData将开始为另一个客户端提供服务的过程(您可以在其构造函数中看到它调用service _-> RequestSayHello,这使系统能够处理另一个传入的RPC)。一旦调用此方法,有关新传入rpc的事件将添加到完成队列中。如果先前的rpc尚未完成,则该rpc的事件将添加到完成队列中。这意味着我们正在使用新的CallData来处理新的rpc,同时使用旧的CallData来处理先前的rpc。



正确,因此在此示例中没有创建新线程。唯一起作用的线程是一个正在运行的HandleRpcs()。因此,当我在上面的答案中谈论“同时”时,这是指在任何时候都在进行多个rpcs(每个rpcs都有自己的CallData),但是由于示例应用程序中只有一个线程,因此处理实际上不是并发的。现在,如果图片中有多个线程,那么保护CallData状态的互斥锁可能是一个好主意(取决于是否可以共享对该状态的访问)。



如果您写的是对代码的唯一更改,则不会,您不需要互斥体(而且我不确定您要尝试调用service_的哪种方法)。

关于c++ - grpc c++异步服务器示例,在处理状态下是否需要互斥锁?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58724528/

10-12 04:47