我有一个需要将任务安排到libuv事件循环的函数。我的想法是创建一个0ms超时的计时器。我尝试了以下代码:
void myFunction() {
...
uv_timer_t* timer = new uv_timer_t();
uv_timer_init(uv_default_loop(), timer);
uv_timer_start(timer, [&](uv_timer_t* timer, int status) {
// Scheduled task
}, 0, 0);
}
这种方法运行良好,但问题是,永远不会释放动态分配的计时器。我已经尝试在回调中释放计时器,但这导致了分段错误:
void myFunction() {
...
uv_timer_t* timer = new uv_timer_t();
uv_timer_init(uv_default_loop(), timer);
uv_timer_start(timer, [&](uv_timer_t* timer, int status) {
// Scheduled task
delete timer;
}, 0, 0);
}
我还试图在实际内存释放之前调用uv_timer_stop(timer);
和uv_unref((uv_handle_t*) timer);
,但分段错误仍然会重新发生。
答案 0 :(得分:8)
我遇到了同样的问题,这就是你处理它的方式:
首先,您需要为计时器句柄关闭时创建一个回调:
void on_timer_close_complete(uv_handle_t* handle)
{
free(handle);
}
请注意,句柄将在回调中释放。
当你停下来并释放你的计时器时,你会这样做:
uv_timer_stop(pTimerHandle);
uv_close((uv_handle_t *)pTimerHandle,on_timer_close_complete);
不直观的部分是uv_close()
电话。我认为我在文档中的任何地方都没有看到它。我只能通过关注来源来解决这个问题。
这样,libuv会在完成计时器后执行你的回调,然后你可以在回调中安全地释放它。
答案 1 :(得分:1)
根据@IntelliAdmin的答案,如果您不想自己关闭它,只是希望在没有更多引用时将其关闭,您可以使用智能指针:
template<typename T>
using deleted_unique_ptr = std::unique_ptr<T, std::function<void( T* )>>;
deleted_unique_ptr<uv_timer_t> timer = deleted_unique_ptr<uv_timer_t>( new uv_timer_t, [&]( uv_timer_t *timerhandl ) {
uv_close( reinterpret_cast<uv_handle_t *>( timerhandl ), OnTimerClose );
});
然后对于回调,只需删除指针:
void OnTimerClose( uv_handle_t *handle )
{
delete handle;
}