其他分享
首页 > 其他分享> > c – 在已经运行的循环上添加另一个计时器

c – 在已经运行的循环上添加另一个计时器

作者:互联网

鉴于以下计划 –

#include <iostream>
#include <uv.h>

int main()
{
    uv_loop_t loop;
    uv_loop_init(&loop);

    std::cout << "Libuv version: " << UV_VERSION_MAJOR << "."
              << UV_VERSION_MINOR << std::endl;

    int r = 0;

    uv_timer_t t1_handle;
    r = uv_timer_init(&loop, &t1_handle);
    uv_timer_start(&t1_handle,
      [](uv_timer_t *t) { std::cout << "Timer1 called\n"; }, 0, 2000);

    uv_run(&loop, UV_RUN_DEFAULT);

    // second timer
    uv_timer_t t2_handle;
    r = uv_timer_init(&loop, &t2_handle);
    uv_timer_start(&t2_handle,
      [](uv_timer_t *t) { std::cout << "Timer2 called\n"; }, 0, 1000);

    uv_loop_close(&loop);
}

第二个计时器句柄永远不会在循环上运行,因为循环已在运行,并且永远不会打印“Timer2 called”.所以我尝试在运行它之后暂时停止循环,然后添加第二个计时器 –

....
uv_run(&loop, UV_RUN_DEFAULT);

// some work

uv_stop(&loop);
// now add second timer
uv_run(&loop, UV_RUN_DEFAULT); // run again
....

但这再次没有用,可能是因为在第一个循环开始运行重复计时器后,后续行将不会被执行.那么我应该如何为已经运行的uvloop添加一个新的计时器句柄?

解决方法:

你是正确的,循环需要在注册新句柄之前停止.在uv_run之后立即调用uv_stop函数无法实现,因为uv_run需要先返回.例如,可以通过使用句柄回调来停止它来实现.这是一个非常愚蠢的例子,说明如何使用现有的Timer1句柄完成它.它在第一次运行时恰好停止循环一次.

#include <iostream>
#include <uv.h>

int main() {
  uv_loop_t loop;
  uv_loop_init(&loop);

  std::cout << "Libuv version: " << UV_VERSION_MAJOR << "." << UV_VERSION_MINOR
            << std::endl;

  int r = 0;

  uv_timer_t t1_handle;
  r = uv_timer_init(&loop, &t1_handle);
  *(bool *)t1_handle.data = true; // need to stop the loop
  uv_timer_start(&t1_handle,
                 [](uv_timer_t *t) {
                   std::cout << "Timer1 called\n";
                   bool to_stop = *(bool *)t->data;
                   if (to_stop) {
                     std::cout << "Stopping loop and resetting the flag\n";
                     uv_stop(t->loop);
                     *(bool *)t->data = false; // do not stop the loop again
                   }
                 },
                 0, 2000);
  uv_run(&loop, UV_RUN_DEFAULT);
  std::cout << "After uv_run\n";

  // second timer
  uv_timer_t t2_handle;
  r = uv_timer_init(&loop, &t2_handle);
  uv_timer_start(&t2_handle,
                 [](uv_timer_t *t) { std::cout << "Timer2 called\n"; }, 0,
                 1000);
  std::cout << "Start loop again\n";
  uv_run(&loop, UV_RUN_DEFAULT);

  uv_loop_close(&loop);
}

所以输出是

Libuv version: 1.9
Timer1 called
Stopping loop and resetting the flag
After uv_run
Start loop again
Timer2 called
Timer2 called
Timer1 called
Timer2 called
Timer2 called
Timer1 called

标签:c-2,linux,c11,libuv
来源: https://codeday.me/bug/20190627/1309669.html