gpt4 book ai didi

c++ - grpc c++ 异步完成队列事件

转载 作者:行者123 更新时间:2023-12-02 10:48:31 24 4
gpt4 key购买 nike

我试图理解 grpc c++ 异步模型流程。这篇文章(link)已经解释了我的很多疑惑。这是 grpc_asycn_server 的代码。为了了解 CompletionQueue 何时获取请求,我添加了一些打印语句,如下所示:

首先在 HandleRpcs() 函数中。

void HandleRpcs() {
// Spawn a new CallData instance to serve new clients.
new CallData(&service_, cq_.get());
void* tag; // uniquely identifies a request.
bool ok;
int i = 0;
while (true) {
std::cout << i << std::endl; ///////////////////////////////
// Block waiting to read the next event from the completion queue. The
// event is uniquely identified by its tag, which in this case is the
// memory address of a CallData instance.
// The return value of Next should always be checked. This return value
// tells us whether there is any kind of event or cq_ is shutting down.
GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
i++;
}
}

以及在proceed()函数内部:

void Proceed() {
if (status_ == CREATE) {
// Make this instance progress to the PROCESS state.
status_ = PROCESS;

// As part of the initial CREATE state, we *request* that the system
// start processing SayHello requests. In this request, "this" acts are
// the tag uniquely identifying the request (so that different CallData
// instances can serve different requests concurrently), in this case
// the memory address of this CallData instance.
std::cout<<"RequestSayHello called"<<std::endl; ////////////////////////////
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
this);
} 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_);

// The actual processing.
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());

// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
status_ = FINISH;
responder_.Finish(reply_, Status::OK, this);
} else {
std::cout<<"deallocated"<<std::endl; ////////////////////////////
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
}

一旦我运行服务器和一个客户端( client ),服务器就会打印以下内容:

RequestSayHello called
i = 0
RequestSayHello called
i = 1
deallocated
i = 2

第二个 RequestSayHello 调用 是有意义的,因为创建了新的 CallData 实例。我的问题是为什么proceed()函数第二次执行并打印dealloced

最佳答案

完成队列 (cq_) 结构处理多种类型的事件,包括请求事件和响应事件。第一次调用 proceed() 进入 CallData 对象状态机的 PROCESS 阶段。

在此阶段:
1. 创建一个新的CallData对象;正如您提到的,这会将请求事件插入到 cq_
2. 使用回复对象调用responder_;这会将响应事件插入到 cq_

收到来自 cq_ 的响应事件后,会在第一个 CallData 对象上再次调用 proceed(),该对象现在位于 FINISH 状态,因此执行清理并打印 dealulated

关于c++ - grpc c++ 异步完成队列事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58499145/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com