如何正确异步使用grpc(ClientAsyncReaderWriter)
Posted
技术标签:
【中文标题】如何正确异步使用grpc(ClientAsyncReaderWriter)【英文标题】:How to correctly use grpc asynchronously (ClientAsyncReaderWriter) 【发布时间】:2017-10-16 09:46:51 【问题描述】:我找不到展示如何使用 ClientAsyncReaderWriter 的 grpc 示例(有吗?)。我自己尝试了一些东西,但是在引用计数方面遇到了麻烦。我的问题来自跟踪代码。
struct grpc_call
有一个 gpr_refcount
类型的成员,称为 ext_ref
。 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() 并注册 Write() (ext_ref == 2
)。
然后它使用 AsyncNext() 来获取标签...必须使用写入或读取操作符。
所以ext_ref > 1
永远,除非 got_event 你不处理。
我这样称呼它:
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
【问题讨论】:
谢谢回复,我已经更新代码了 有一个asynchronous example here。如果没有真正深入了解您所询问的具体内容,您是否觉得您所面临的问题存在于该示例中?你所做的有什么不同? 感谢您一直以来对我的关注。但我不喜欢这个问题。我编译示例,发现它使用类 ClientAsyncResponseReader,当使用 AsyncSayHello 注册调用时,关键是 ClientAsyncResponseReader 使用 SneakyCallOpSet 进行初始化。比使用 Next() ,它调用 FinalizeResult() 并返回 false。所以 UNREF ext_ref 操作两次。但我使用 ClientAsyncReaderWriter 传输流 grpc。这一切都使用CallOpSet。那你能告诉我如何使用客户端 AsyncReadWrite 吗? 我只是想帮助你,虽然我知道 C++,但我对此一无所知。看起来您正在查看一个详细的问题并且有(英语)语言障碍,并且您是 *** 的新用户,所以我想给您对这里的人的积极印象。但也许要做的事情是继续编辑,直到您确定您表达了误解,并要求开发人员来这里做出回应。 *** 是一个很好的网站,但只有遵循协议才能为您提供帮助。 非常感谢您的慷慨帮助。谢谢你给了这么多建议。我想知道如何使用 ClientAsyncReaderWriter。 【参考方案1】:看看这个文件,client_async.cc,很好地使用 ClientAsyncReaderWriter。如果您仍然有困惑,请创建一个非常清晰的问题重现,我们将进一步调查。
【讨论】:
以上是关于如何正确异步使用grpc(ClientAsyncReaderWriter)的主要内容,如果未能解决你的问题,请参考以下文章