带有 libev 和自定义事件循环的 C++ libhiredis
C++ libhiredis with libev and custom event loop
我的应用程序使用带有 libev 后端的 libhiredis。我需要发送 Redis 异步命令并处理生成的 Redis 异步回调。但是,与 here 中的简单示例不同,我不能使用默认事件循环。以下代码近似于带有自定义事件循环的示例。然而,当仅使用 redisLibevAttach()
诱导的 libev io 观察器编译时,事件循环线程立即终止。你可以通过运行
看到这个
g++ -g -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev && gdb ./hiredis_ev
其中 GDB 愉快地打印出一个新线程已创建并且几乎立即终止。 GDB 中 运行 info thread
没有显示 my_ev_loop
进一步证实了这一点。但是,如果我更改代码以添加任何其他 libev 观察器,如计时器,那么一切都很好。你可以通过运行
看到这个
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
找到
我的应用程序使用带有 libev 后端的 libhiredis。我需要发送 Redis 异步命令并处理生成的 Redis 异步回调。但是,与 here 中的简单示例不同,我不能使用默认事件循环。以下代码近似于带有自定义事件循环的示例。然而,当仅使用 redisLibevAttach()
诱导的 libev io 观察器编译时,事件循环线程立即终止。你可以通过运行
g++ -g -std=c++11 -Wall -Wextra -Werror hiredis_ev.cpp -o hiredis_ev -lpthread -lhiredis -lev && gdb ./hiredis_ev
其中 GDB 愉快地打印出一个新线程已创建并且几乎立即终止。 GDB 中 运行 info thread
没有显示 my_ev_loop
进一步证实了这一点。但是,如果我更改代码以添加任何其他 libev 观察器,如计时器,那么一切都很好。你可以通过运行
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
找到