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());
答案 0 :(得分:1)
我会尽力回答您的每个问题。
我对这句话有些困惑,因为它似乎暗示新的CallData>实例可以同时为另一个客户端提供服务。 (这是> loop事件吗?)
这里的事件循环是HandleRpcs()中cq _-> Next()的循环。创建新的CallData将开始为另一个客户端提供服务的过程(您可以在其构造函数中看到它调用service _-> RequestSayHello,这使系统能够处理另一个传入的RPC)。一旦调用此方法,有关新传入rpc的事件将添加到完成队列中。如果先前的rpc尚未完成,则该rpc的事件将添加到完成队列中。这意味着我们正在使用新的CallData来处理新的rpc,同时使用旧的CallData来处理先前的rpc。
我正确地假设没有创建新线程并且没有共享变量 可以对CallData起作用,不需要互斥体吗?还是需要互斥锁?
正确,因此在此示例中没有创建新线程。唯一起作用的线程是一个正在运行的HandleRpcs()。因此,当我在上面的答案中谈论“同时”时,这是指在任何时间都在进行多个rpcs(每个rpcs都有自己的CallData),但实际上处理不是并发的,因为示例应用程序中只有一个线程。现在,如果图片中有多个线程,那么保护CallData状态的互斥锁可能是一个好主意(取决于是否可以共享访问状态)。
例如,如果示例中的代码更改为以下代码,我是否需要互斥锁?
如果您写的是对代码的唯一更改,则不会,您不需要互斥体(而且我不确定无论如何您都想在service_上调用哪种方法)。