c++ - 具有libev和自定义事件循环的C++ libhiredis

标签 c++ redis event-loop hiredis libev

我的应用程序将libhiredis与libev后端一起使用。我需要发送Redis异步命令并处理生成的Redis异步回调。但是,与here中的简单示例不同,我无法使用默认事件循环。以下代码使用自定义事件循环来近似示例。但是,当仅使用由redisLibevAttach()引发的libev io watcher进行编译时,事件循环线程将立即终止。您可以通过运行查看

g++ -g -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev && gdb ./hiredis_ev

GDB高兴地打印出一个新线程已创建并几乎立即终止的地方。通过在GDB中运行不显示info threadmy_ev_loop可以进一步确认这一点。但是,如果我更改代码以添加任何其他libev watcher(如计时器),那么一切都很好。您可以通过运行查看

g++ -g -DTIMER -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev &&  ./hiredis_ev

我不需要虚拟的libev计时器来保持事件循环运行。我想念什么?

#include <iostream>
#include <thread>
#include <hiredis/hiredis.h>
#include <hiredis/async.h>
#include <hiredis/adapters/libev.h>

static struct ev_loop *loop = nullptr;
static void redis_async_cb(redisAsyncContext *, void *, void *)
{
  std::cout << "Redis async callback" << std::endl;
  fflush(nullptr);
}

#ifdef TIMER
  static ev_timer timer_w;
  static void ev_timer_cb(EV_P_ ev_timer *, int)
  {
    std::cout << "EV timer callback" << std::endl;
    fflush(nullptr);
  }
#endif

int main()
{
  loop = ev_loop_new(EVFLAG_AUTO);

#ifdef TIMER
  ev_timer_init(&timer_w, ev_timer_cb, 0, 0.1);
  ev_timer_start(loop, &timer_w);
#endif

  redisAsyncContext* async_context = redisAsyncConnect("localhost", 6379);
  if (nullptr == async_context)
  {
    throw std::runtime_error("No redis async context");
  }

  redisLibevAttach(loop, async_context);
  std::thread ev_thread(ev_run, loop, 0); 
  pthread_setname_np(ev_thread.native_handle(), "my_ev_loop");
  ev_thread.detach();

  // Give the event loop time to start
  while (!ev_iteration(loop))
  {
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  }

  // Send a SUBSCRIBE message which should generate an async callback
  if (REDIS_OK != redisAsyncCommand(async_context, redis_async_cb, nullptr, "SUBSCRIBE foo"))
  {
    throw std::runtime_error("Could not issue redis async command");
  }
  std::cout << "Waiting for async callback" << std::endl;
  fflush(nullptr);
    fflush(nullptr);

  // Wait forever (use CTRL-C to terminate)
  while (true)
  {
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  }

  return 0;
}

最佳答案

我发现hiredis社区有自己的GitHub实例,可以在其中提问。由于我还没有在这里收到答案,所以我在那儿提问。答案可以在https://github.com/redis/hiredis/issues/801#issuecomment-626400959找到

关于c++ - 具有libev和自定义事件循环的C++ libhiredis,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61680255/

相关文章:

caching - Redis作为服务启动【无法识别的服务错误】

javascript - NodeJS 事件循环中的 process.nextTick() 何时被调用?

javascript - nodejs : setImmediate callback executed after setTimeout(fn, 0) 与 nodejs 文档描述不一致

c++ - 高效的 SSE NxN 矩阵乘法

c++ - 从继承的类实例调用静态成员

c++ - 对于基于 Arduino Sketch 的照度计, 'loop' 之外的功能不会被触发/触发

redis - 在 appveyor 上启动 redis-server

redis - 使用 Redis 无需停机即可丢失数据

javascript - 为什么Javascript事件循环需要全局执行上下文在执行回调队列中的函数之前完成运行

c++ - log4cpp 给出 `unresolved external` 错误