2016-10-09 3 views
6

Учитывая следующую программу -добавить еще один таймер на уже запущен цикл

#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 под названием» никогда не печатается. Так что я пытался остановить цикл временно после запуска его, а затем добавить второй таймер -

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

// some work 

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

Но это опять-таки не получилось, наверное, потому, что последующие строки не будут выполняться после того, как первый цикл начинает работать с повторением таймер. Итак, как мне добавить новый дескриптор таймера к уже запущенному uvloop?

ответ

1

Вы правы, что цикл должен быть остановлен, прежде чем он сможет зарегистрировать новый дескриптор. Этого не может быть достигнуто путем вызова функции uv_stop сразу после uv_run, потому что 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 
+0

круто, так что мы можем манипулировать цикл в пределах его функции обратного вызова, только убедившись, что мы остановили его первым. –

 Смежные вопросы

  • Нет связанных вопросов^_^