2016-10-09 10 views
6

Biorąc pod uwagę następujący program -dodać inny timer na już działa pętla

#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); 
} 

Drugi uchwyt czasowy nie jest prowadzony na pętli, ponieważ pętla jest już uruchomiony, a „Timer2 zwany” nigdy nie zostanie wydrukowany. Więc próbowałem zatrzymać pętlę chwilowo po uruchomieniu go, a następnie dodając drugi timer -

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

// some work 

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

Ale to znowu nie działa, prawdopodobnie dlatego, że późniejsze linie nie będą wykonywane po uruchomieniu 1-ty pętla działa z powtórzenie regulator czasowy. Jak więc dodać nowy uchwyt timera do już działającego uvloopa?

Odpowiedz

1

Masz rację, pętla musi zostać zatrzymana, zanim będzie mogła zarejestrować nowy uchwyt. Nie można tego osiągnąć, wywołując funkcję uv_stop zaraz po uv_run, ponieważ uv_run musi najpierw powrócić. Można to osiągnąć na przykład zatrzymując go za pomocą wywołania zwrotnego. Oto dość głupi przykład tego, jak można to zrobić przy użyciu istniejącego uchwytu Timer1. Zatrzymuje pętlę dokładnie jeden raz przy pierwszym uruchomieniu.

#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); 
} 

więc wyjście jest

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

chłodny, więc możemy manipulować Loop to funkcje wywołania zwrotnego, tylko upewniając się, że przestałem go jako pierwszy. –