2

我有一个需要将任务安排到 libuv 事件循环的函数。我的想法是创建一个超时时间为 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
    }, 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);and uv_unref((uv_handle_t*) timer);,但分段错误仍然存​​在。

4

2 回答 2

9

我有同样的问题,这是你处理它的方式:

首先,您需要为计时器句柄关闭时创建一个回调:

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 将在计时器完成后执行您的回调,然后您可以在该回调中安全地释放它。

于 2013-12-03T19:35:32.677 回答
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;
}
于 2016-05-16T19:26:57.713 回答