c++libhiredis

wkyowqbh  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(408)

我的应用程序使用libhiredis和libev后端。我需要发送redis async命令并处理结果redis async回调。但是,与这里的简单示例不同,我不能使用默认的事件循环。下面的代码使用一个自定义事件循环来近似该示例。但是,当只使用 redisLibevAttach() 引发libev io watcher,事件循环线程立即终止。你可以通过跑步看到这一点

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

gdb愉快地打印出一个新线程被创建并几乎立即终止。通过运行进一步证实了这一点 info thread 在gdb中不显示 my_ev_loop . 但是,如果我修改代码来添加其他libev观察者,比如计时器,那么一切都很好。你可以通过跑步看到这一点

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

我不需要一个虚拟libev计时器来保持事件循环运行。我错过了什么?

  1. # include <iostream>
  2. # include <thread>
  3. # include <hiredis/hiredis.h>
  4. # include <hiredis/async.h>
  5. # include <hiredis/adapters/libev.h>
  6. static struct ev_loop *loop = nullptr;
  7. static void redis_async_cb(redisAsyncContext *, void *, void *)
  8. {
  9. std::cout << "Redis async callback" << std::endl;
  10. fflush(nullptr);
  11. }
  12. # ifdef TIMER
  13. static ev_timer timer_w;
  14. static void ev_timer_cb(EV_P_ ev_timer *, int)
  15. {
  16. std::cout << "EV timer callback" << std::endl;
  17. fflush(nullptr);
  18. }
  19. # endif
  20. int main()
  21. {
  22. loop = ev_loop_new(EVFLAG_AUTO);
  23. # ifdef TIMER
  24. ev_timer_init(&timer_w, ev_timer_cb, 0, 0.1);
  25. ev_timer_start(loop, &timer_w);
  26. # endif
  27. redisAsyncContext* async_context = redisAsyncConnect("localhost", 6379);
  28. if (nullptr == async_context)
  29. {
  30. throw std::runtime_error("No redis async context");
  31. }
  32. redisLibevAttach(loop, async_context);
  33. std::thread ev_thread(ev_run, loop, 0);
  34. pthread_setname_np(ev_thread.native_handle(), "my_ev_loop");
  35. ev_thread.detach();
  36. // Give the event loop time to start
  37. while (!ev_iteration(loop))
  38. {
  39. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  40. }
  41. // Send a SUBSCRIBE message which should generate an async callback
  42. if (REDIS_OK != redisAsyncCommand(async_context, redis_async_cb, nullptr, "SUBSCRIBE foo"))
  43. {
  44. throw std::runtime_error("Could not issue redis async command");
  45. }
  46. std::cout << "Waiting for async callback" << std::endl;
  47. fflush(nullptr);
  48. fflush(nullptr);
  49. // Wait forever (use CTRL-C to terminate)
  50. while (true)
  51. {
  52. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  53. }
  54. return 0;
  55. }
35g0bw71

35g0bw711#

我发现hiredis社区有自己的github示例,我可以在那里提问。因为我在这里还没有得到答案,所以我在那里问。答案可以在https://github.com/redis/hiredis/issues/801#issuecomment-626400959

相关问题