2016-08-13 2 views
1

Die usecaseeinfache Timer-Ereignisschleife

Ich bin ein C-Programm zu schreiben, das mehrere Timer benötigt. Ich hatte zuerst einen schnellen Prototyp geschrieben, der für jeden Timer einen pthread startete. Nur eine einfache while -loop mit einem sleep Befehl, weil 1 Sekunde Auflösung ist genug.

Aber mit mehr als 10 Timern ist es nicht eine sehr effiziente noch Produktionsqualität Codequalität. Daher wollte ich eine Eventloop verwenden. Ich habe mehrmals über libuv gelesen und dachte mir, es einmal auszuprobieren.

Also meine Idee war einfach. Habe 1 Timer-Thread, der den Timer Eventloop ausführt und Timer im laufenden Betrieb hinzufügt und entfernt. Die Timer sind sehr einfache Countdown-Timer, die einen Funktionszeiger ausführen, wenn sie 0 erreichen und die gelöscht werden können. Daher ist keine Wiederholung erforderlich.

Das Problem

Ich denke, hier ist das eigentliche Problem der Dokumentation ist, sind die libuv docs einfach nicht ganz klar, wie dies zu erreichen. Also ich denke, der Code, den ich derzeit habe, ist Quatsch. Lass mich dich durchgehen.

Zu Beginn meines Programms Ich fange an phtread mit folgendem Einstiegspunkt:

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

als wann immer ich will ich einen Timer verwenden, würde folgendes tun:

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

Jetzt Ich habe mehrere Fragen:

  1. So verwenden Sie den Timer ohne Wiederholung
  2. Wo finde ich die Callback-Funktion für diesen Timer
  3. eingestellt Wie kann ich, wie viel Zeit wissen, in diesem Timer

ich zu diesem Thema kann wirklich etwas Hilfe verlassen wird.

Update 1

Ok, ich mache Fortschritte und es funktioniert im Grunde. Die libuv-Ereignisschleife wird in einem separaten Thread ausgeführt. Und schon einige meiner Fragen zu beantworten:

  1. Wenn das letzte Argument in uv_timer_start 0 wird der Timer wird sich nicht wiederholen.

  2. Der Rückruf für die Timeout-Ereignis-Timer ist das zweite Argument von uv_timer_start

Ich weiß noch nicht die beste Antwort auf meine dritte Frage. Aber im Moment verfolge ich die Zeit, wann mein Timer gestartet wurde und die aktuelle Zeit und nehme den Unterschied. Ich subtrahiere dann die Differenz von der Gesamtzeit des Timers, um zu wissen, wie lange es dauert, bis der Timer endet.

Ich möchte immer noch wissen, ob meine uv_run Implementierung korrekt ist.

Mit freundlichen Grüßen, Daan

+2

Sie sprechen über Pthreads, die sehr gut dokumentiert sind, aber libuv verwenden. Also benutzt du pthreads nicht an erster Stelle. Verwenden Sie pthreads und Ihr Dokumentationsproblem wird gelöst. – Olaf

+0

Wie ist 'timer_event_loop' definiert? – alk

+0

Es ist ein Zeiger oben in der C-Datei. –

Antwort

2

Sie sind nicht definiertes Verhalten Gebiet spielen. libuv ist nicht Thread-sicher see the docs here Also während der Schleife in einem Thread ausgeführt wird, ist ok, einen Timer in einem anderen Thread erstellen, während die Schleife ausgeführt wird, ist nicht in Ordnung.

Sie können es immer noch tun, indem Sie einen uv_async_t Handle und einen Semaphor verwenden: uv_async_send ist threadsicher, also würden Sie es von außen nennen, die Schleife anhalten und ein Semaphor signalisieren. Der aufrufende Thread würde warten, bis der Semaphor signalisiert wird. An diesem Punkt wird die Schleife gestoppt, es ist also in Ordnung, einen neuen Timer zu erstellen und hinzuzufügen.

Es gibt keine API, um zu wissen, wie viel Zeit ein Timer hat.

Wenn Sie nur eine Schleife brauchen, um einige Timer zu steuern, könnte libuv übertrieben sein. Sie können timerfd verwenden, wenn Sie unter Linux sind, oder eine von Hand erstellte Ereignisschleife, die nur Timer zum Beispiel auf select setzt.

+0

Vielen Dank Ich habe einen eventloop mit epoll und timerfd geschrieben, es ist jetzt Thread-sicher und funktioniert ohne den libuv overhead. –