为什么 GRPC AsyncClient 在等待完成队列中的下一个结果时抛出段错误
why GRPC AsyncClient throws Segfault when waiting for the Next result in the completion queue
我正在使用 GRPC 库的版本 1.23.1。
我有一个异步 RPC c++ Client
class,它使用以下方法启动每个 RPC:
void Client::SendTaskAsync(const Task& task) {
unique_lock<mutex> lock(mtx_);
cout << "Sending task with id " << task.id() << endl;
ClientContext context;
Status status;
unique_ptr<ClientAsyncResponseReader<Result>> rpc(
stub_->PrepareAsyncSendTask(&context, task, &queue_));
rpc->StartCall();
// Allocating memory to store result from RPC
Result* result = &results_.emplace_back();
int* tag = new int(results_.size() - 1);
rpc->Finish(result, &status, static_cast<void*>(tag));
}
在主线程中我循环调用了五次SendTaskAsync
。
Client
class 有一个后台线程通知每个 RPC 何时返回结果:
while (true) {
void* tag;
bool ok = false;
{
unique_lock<mutex> lock(mtx_);
cout << "Waiting the for next result" << endl;
const time_point<system_clock> deadline =
system_clock::now() + milliseconds(1000);
// SEGFAULT HERE, WHY?
GPR_ASSERT(queue_.AsyncNext(&tag, &ok, deadline));
}
if (ok) {
int index = *static_cast<int*>(tag);
cout << "Got result with tag " << index << endl;
} else {
cout << "Sleeping" << endl;
sleep_for(milliseconds(1000));
}
}
如果我启动客户端,会观察到以下日志:
BACKGROUND: Waiting for the next result
MAIN THREAD: Sending task with id 0
BACKGROUND: Sleeping
MAIN THREAD: Sending task with id 1
MAIN THREAD: Sending task with id 2
MAIN THREAD: Sending task with id 3
MAIN THREAD: Sending task with id 4
BACKGROUND: Waiting for the next result
BACKGROUND: Segmentation fault (core dumped)
发生的事情是
后台线程检查queue_
是否有结果,还有none,所以进入休眠;
主线程进行 5 个 RPC,最后应该用结果填充 queue_
;
后台线程唤醒并检查 queue_
是否包含结果,AND CRASHES.
知道为什么吗?
问题中的代码是按照this tutorial写的,只发送一个请求,在同一个线程中等待回复
如果要使用多线程,请按照客户端示例here。
我正在使用 GRPC 库的版本 1.23.1。
我有一个异步 RPC c++ Client
class,它使用以下方法启动每个 RPC:
void Client::SendTaskAsync(const Task& task) {
unique_lock<mutex> lock(mtx_);
cout << "Sending task with id " << task.id() << endl;
ClientContext context;
Status status;
unique_ptr<ClientAsyncResponseReader<Result>> rpc(
stub_->PrepareAsyncSendTask(&context, task, &queue_));
rpc->StartCall();
// Allocating memory to store result from RPC
Result* result = &results_.emplace_back();
int* tag = new int(results_.size() - 1);
rpc->Finish(result, &status, static_cast<void*>(tag));
}
在主线程中我循环调用了五次SendTaskAsync
。
Client
class 有一个后台线程通知每个 RPC 何时返回结果:
while (true) {
void* tag;
bool ok = false;
{
unique_lock<mutex> lock(mtx_);
cout << "Waiting the for next result" << endl;
const time_point<system_clock> deadline =
system_clock::now() + milliseconds(1000);
// SEGFAULT HERE, WHY?
GPR_ASSERT(queue_.AsyncNext(&tag, &ok, deadline));
}
if (ok) {
int index = *static_cast<int*>(tag);
cout << "Got result with tag " << index << endl;
} else {
cout << "Sleeping" << endl;
sleep_for(milliseconds(1000));
}
}
如果我启动客户端,会观察到以下日志:
BACKGROUND: Waiting for the next result
MAIN THREAD: Sending task with id 0
BACKGROUND: Sleeping
MAIN THREAD: Sending task with id 1
MAIN THREAD: Sending task with id 2
MAIN THREAD: Sending task with id 3
MAIN THREAD: Sending task with id 4
BACKGROUND: Waiting for the next result
BACKGROUND: Segmentation fault (core dumped)
发生的事情是
后台线程检查
queue_
是否有结果,还有none,所以进入休眠;主线程进行 5 个 RPC,最后应该用结果填充
queue_
;后台线程唤醒并检查
queue_
是否包含结果,AND CRASHES.
知道为什么吗?
问题中的代码是按照this tutorial写的,只发送一个请求,在同一个线程中等待回复
如果要使用多线程,请按照客户端示例here。