【问题标题】:Simple timer event loop简单的定时器事件循环
【发布时间】:2016-08-13 13:40:35
【问题描述】:

用例

我正在编写一个需要多个计时器的 C 程序。我首先编写了一个快速原型,它为每个计时器启动了一个pthread。只需一个简单的 while-loop 和 sleep 命令,因为 1 秒的分辨率就足够了。

但是如果有超过 10 个计时器,这不是一个非常有效的代码质量,也不是生产级代码质量。因此我想使用一个事件循环。我已经阅读了好几遍关于 libuv 的文章,并想尝试一下。

所以我的想法很简单。有 1 个计时器线程,它运行计时器事件循环并动态添加和删除计时器。定时器是非常简单的倒计时定时器,当它们到达 0 时执行一个函数指针,并且可以取消。所以不需要重复。

问题

我认为这里真正的问题是文档,libuv 文档对于如何实现这一点并不是很清楚。所以我认为我目前拥有的代码是垃圾。让我带你了解一下。

在我的程序开始时,我使用以下入口点启动一个 phtread:

static void* _uv_loop_thread_entry_point(void *args)
{
    /* Initialize the timer event loop */
    timer_event_loop = malloc(sizeof(uv_loop_t));
    uv_loop_init(timer_event_loop);

    /* Keep running the eventloop */
    while(uv_run(timer_event_loop, UV_RUN_DEFAULT) == 0) {
        /* Wait 1 second for new handles */
        sleep(1);
    };

    /* The timer event loop has stopped, free all resources */
    uv_loop_close(timer_event_loop);
    free(timer_event_loop);

    return NULL;
}

每当我想使用计时器时,我都会执行以下操作:

uv_timer_init(timer_event_loop, uv_timer);
uv_timer_start(uv_timer, timeout_ms, ??);

现在我有几个问题:

  1. 如何使用计时器而不重复
  2. 在哪里设置这个定时器的回调函数
  3. 我怎么知道这个计时器还剩多少时间

我真的可以在这个问题上使用一些帮助。

更新 1

好的,我正在取得一些进展,它基本上可以工作。 libuv 事件循环在单独的线程中运行。并且已经回答了我的一些问题:

  1. uv_timer_start 中的最后一个参数为0 时,计时器将不会重复。

  2. 定时器超时事件的回调是uv_timer_start的第二个参数

我还不知道第三个问题的最佳答案。但是现在我会跟踪我的计时器开始的时间和当前时间,并计算差异。我从计时器的总时间中减去差异,以了解计时器结束之前需要多长时间。

我仍然想知道我的uv_run 实现是否正确。

亲切的问候, 大安

【问题讨论】:

  • 你谈到了 pthreads,它有很好的文档记录,但是使用 libuv。所以你首先不要使用pthreads。使用 pthreads,您的文档问题将得到解决。
  • timer_event_loop 是如何定义的?
  • 是C文件顶部的指针。

标签: c timer libuv


【解决方案1】:

您在未定义的行为领域中玩耍。 libuv 不是线程安全的see the docs here 所以在一个线程中运行循环是可以的,但在循环运行时在另一个线程中创建一个计时器是不行的。

您仍然可以通过使用uv_async_t 句柄和信号量来做到这一点:uv_async_send 是线程安全的,因此您可以从外部调用它,停止循环并发出信号量信号。调用线程将等到信号量发出信号。至此循环停止,创建新定时器并添加即可。

没有 API 可以知道计时器还剩多少时间。

如果你只需要一个循环来控制一些计时器,libuv 可能会有点过分。如果你在 Linux 上,你可以使用 timerfd,或者手动构建的事件循环,例如,它只在 select 之上执行计时器。

【讨论】:

  • 非常感谢,我用 epoll 和 timerfd 编写了一个事件循环,它现在是线程安全的,并且可以在没有 libuv 开销的情况下工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-17
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多