如何正确异步使用grpc(ClientAsyncReaderWriter)
How to correctly use grpc asynchronously (ClientAsyncReaderWriter)
我找不到显示如何使用ClientAsyncReaderWriter的grpc示例(有吗?)。我自己尝试了一些东西,但在引用计数方面遇到了问题。我的问题来自于对代码的追踪。
CCD_ 1具有被称为CCD_ 3的CCD_。ClientContext C++对象包装grpc_call,并将其保存在成员grpc_call *call_;
中。只有当ext_ref为0时,才能删除此grpc_call指针。
当我与ClientReader同步使用grpc时:
- 在其实现中,它使用CreateCall()和PerformOps()添加到ext_ref(
ext_ref == 2
) - 然后我使用Pluck(),它从ext_ref中减去,使得(
ext_ref == 1
) - 最后一次使用~ClientContext()从ext_ref中减去,以便
ext_ref == 0
并删除调用
但是当我与ClientAsyncReaderWriter异步使用grpc时:
- 首先使用asyncXXX(),这个API使用CreateCall()和register Write()(
ext_ref == 2
) - 然后它使用AsyncNext()来获取标记。。。其必须使用写入或读取运算符
- 所以
ext_ref > 1
永远存在,除非发生你无法处理的事件
我这样称呼它:
struct Notice
{
std::unique_ptr<
grpc::ClientAsyncReaderWriter<ObserveNoticRequest, EventNotice>
> _rw;
ClientContext _context;
EventNotice _rsp;
}
注册线程
CompletionQueue *cq = new CompletionQueue;
Notice *notice = new Notice;
notice->rw = stub->AsyncobserverNotice(&context, cq, notice);
// here context.call_.ext_ref is 2
获取CompletionQueue事件线程
void *tag = NULL;
bool ok = false;
CompletionQueue::NextStatus got = CompletionQueue::NextStatus::TIMEOUT;
gpr_timespec deadline;
deadline.clock_type = GPR_TIMESPAN;
deadline.tv_sec = 0;
deadline.tv_nsec = 10000000;
got = cq->AsyncNext<gpr_timespec>(&tag, &ok, deadline);
if (GOT_EVENT == got) {
if (tag != NULL) {
Notice *notice = (Notice *)tag;
notice->_rw->Read(&_rsp, notice);
// here context.call_.ext_ref is 2.
// now I want to stop this CompletionQueue.
delete notice;
// use ~ClientContext(), ext_ref change to 1
// but only ext_ref == 0, call_ be deleted
}
}
查看此文件client_async.cc,以了解ClientAsyncReaderWriter的良好使用情况。如果您仍有困惑,请创建一个非常干净的问题复制品,我们将对此进行进一步调查。
相关文章:
- 没有找到相关文章