gpt4 book ai didi

c++ - 如何正确异步使用grpc(ClientAsyncReaderWriter)

转载 作者:搜寻专家 更新时间:2023-10-31 02:09:12 27 4
gpt4 key购买 nike

我找不到展示如何使用 ClientAsyncReaderWriter 的 grpc 示例(有吗?)。我自己尝试了一些东西,但在引用计数方面遇到了问题。我的问题来自对代码的跟踪。

struct grpc_call有一个类型为 gpr_refcount 的成员称为 ext_ref。 ClientContext C++ 对象包装了 grpc_call,并在成员 grpc_call *call_; 中保留它.只有当ext_ref为0时,才能删除这个grpc_call指针。

当我将 grpc 与 ClientReader 同步使用时:

  • 在其实现中,它使用 CreateCall() 和 PerformOps() 添加到 ext_ref (ext_ref == 2)。
  • 然后我使用 Pluck() 从 ext_ref 中减去,以便 (ext_ref == 1)。
  • 最后使用~ClientContext()从ext_ref中减去,使得ext_ref == 0并删除调用

但是当我将 grpc 与 ClientAsyncReaderWriter 异步使用时:

  • 首先使用 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
}
}

最佳答案

看看这个文件,client_async.cc , 以便更好地使用 ClientAsyncReaderWriter。如果您仍然感到困惑,请创建一个非常清晰的问题重现,我们将进一步调查。

关于c++ - 如何正确异步使用grpc(ClientAsyncReaderWriter),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46767347/

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