首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用select()和gRPC创建服务器?

如何使用select()和gRPC创建服务器?
EN

Stack Overflow用户
提问于 2016-09-22 03:15:52
回答 2查看 735关注 0票数 1

我需要在单线程应用程序中使用gRPC (带有额外的套接字通道)。我天真地考虑使用select(),并根据弹出的文件描述符调用gRPC来处理消息。我的问题是,有人能给我一个粗略的(5-10行代码)框架,告诉我在select()弹出后我需要调用什么?

在同步情况下,Google的"hello world“示例暗示了一个线程池(我不能使用它),而在异步情况下,显示了主循环阻塞--这对我不起作用,因为我需要处理其他套接字操作。

EN

回答 2

Stack Overflow用户

发布于 2016-09-28 06:49:12

在这一点上,你不能这样做(可能永远都不会)。

事件循环的一大弱点,包括直接使用select()/poll()风格的API,是它们不能以任何自然的方式组合,除非两者之间的直接集成。

从理论上讲,我们可以为Linux添加这样的功能--导出一个带有定时器and的epoll_fd,如果调用完成队列是有效的,那么这个定时器就会变得可读,但是这样做会对堆栈的其余部分施加大量的约束和架构开销,仅仅是为了在Linux上支持这个用例。其他任何地方都需要一个后台线程来管理fd的可读性。

票数 1
EN

Stack Overflow用户

发布于 2022-02-09 06:33:58

这可以使用gRPC异步服务和grpc::Alarm将来自select或其他轮询API的任何事件发送到gRPC完成队列。您可以在this gist中看到同时使用Epoll和gRPC的示例。重要的功能是这两个:

代码语言:javascript
复制
bool grpc_tick(grpc::ServerCompletionQueue& queue) {
  void* tag = nullptr;
  bool ok = false;
  auto next_status = queue.AsyncNext(&tag, &ok, std::chrono::system_clock::now());
  if (next_status == grpc::CompletionQueue::GOT_EVENT) {
    if (ok && tag) {
      static_cast<RequestProcessor*>(tag)->grpc_queue_tick();
    } else {
      std::cerr << "Not OK or bad tag: " << ok << "; " << tag << std::endl;
      return false;
    }
  }
  return next_status != grpc::CompletionQueue::SHUTDOWN;
}

bool tick_loops(int epoll, grpc::ServerCompletionQueue& queue) {
  // Pump epoll events over to gRPC's completion queue.
  epoll_event event{0};
  while (epoll_wait(epoll, &event, /*maxevents=*/1, /*timeout=*/0)) {
    grpc::Alarm alarm;
    alarm.Set(&queue, std::chrono::system_clock::now(), event.data.ptr);
    if (!grpc_tick(queue)) return false;
  }

  // Make sure gRPC gets at least 1 tick.
  return grpc_tick(queue);
}

在这里,您可以看到tick_loops函数反复调用epoll_wait,直到不再返回任何事件。对于每个epoll事件,都会构造一个grpc::Alarm,并将截止日期设置为now。在此之后,将立即使用grpc_tick抽出gRPC事件循环。

请注意,grpc::Alarm实例的生存时间必须超过其在完成队列中的时间。在真实的应用程序中,应该以某种方式将警报附加到标记(本例中为event.data.ptr),以便在完成回调中将其清除。

然后再次抽出gRPC事件循环,以确保也处理任何非epoll事件。

完成队列是线程安全的,因此您还可以将epoll泵放在一个线程上,将gRPC泵放在另一个线程上。使用此设置,您不需要像本例中那样将每个轮询超时设置为0。这将通过限制事件循环泵的干周期来减少CPU使用量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39624822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档