[英]C++ libhiredis with libev and custom event loop
My application uses libhiredis with libev backend.我的应用程序使用带有 libev 后端的 libhiredis。 I need to send Redis async commands and process the resulting Redis async callback.
我需要发送 Redis 异步命令并处理生成的 Redis 异步回调。 However, unlike the simple example from here I cannot use the default event loop.
但是,与此处的简单示例不同,我不能使用默认事件循环。 The following code approximates the example with a custom event loop.
以下代码使用自定义事件循环近似示例。 However, when compiled with only the
redisLibevAttach()
induced libev io watcher, the event loop thread terminates immediately.但是,当仅使用
redisLibevAttach()
诱导的 libev io 观察程序进行编译时,事件循环线程会立即终止。 You can see this by running您可以通过运行看到这一点
g++ -g -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev && gdb ./hiredis_ev
where GDB happily prints that a new thread is created and almost immediately terminates. GDB 高兴地打印出一个新线程已创建并几乎立即终止。 This is further confirmed by running
info thread
in GDB which does not show my_ev_loop
.通过在 GDB 中运行未显示
my_ev_loop
的info thread
进一步证实了这一点。 However, if I change the code to add any other libev watcher, like a timer, then everything is good.但是,如果我更改代码以添加任何其他 libev 观察程序,例如计时器,那么一切都很好。 You can see this by running
您可以通过运行看到这一点
g++ -g -DTIMER -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev && ./hiredis_ev
I should not need a dummy libev timer to keep the event loop running.我不应该需要一个虚拟的 libev 计时器来保持事件循环运行。 What am I missing?
我错过了什么?
#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;
}
I found out that hiredis community has their own GitHub instance where I can ask questions.我发现hiredis 社区有他们自己的GitHub 实例,我可以在其中提问。 Since I had't yet received the answer here, I asked there.
由于我在这里还没有收到答案,所以我在那里问。 The answer can be found at https://github.com/redis/hiredis/issues/801#issuecomment-626400959
答案可以在https://github.com/redis/hiredis/issues/801#issuecomment-626400959找到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.