2013-06-14 12 views
7

Quando si esegue un ciclo di eventi in libuv utilizzando la funzione uv_run, c'è un parametro "mode" che viene utilizzato con i seguenti valori:Come funziona la modalità UV_RUN_NOWAIT in libuv?

UV_RUN_DEFAULT 
UV_RUN_ONCE 
UV_RUN_NOWAIT 

I primi due sono evidenti. UV_RUN_DEFAULT esegue il ciclo di eventi fino a quando non ci sono più eventi e UV_RUN_ONCE elaborando un singolo evento dal ciclo. Tuttavia, UV_RUN_NOWAIT non sembra essere una modalità separata, ma piuttosto un flag che può essere OR con uno degli altri due valori.

Per impostazione predefinita, questa funzione si blocca fino a quando gli eventi non vengono elaborati e UV_RUN_NOWAIT lo rende non bloccante, ma la documentazione che riesco a trovare finisce lì. La mia domanda è, se si esegue il ciclo di eventi non bloccante, come vengono gestiti i callback?

Il modello di eventi libuv è thread singolo (modello reattore), quindi vi impegna deve bloccare per essere in grado di chiamare i callback, ma se il filo principale è occupato, cosa succede ad un evento dopo averlo elaborato ? La callback sarà "accodata" fino a quando libuv non riprenderà il controllo del thread principale? O i callback saranno spediti su un altro thread?

risposta

9

Le richiamate vengono gestite allo stesso modo. Eseguiranno all'interno del thread che si trova in uv_run().

Per la documentation:

  • UV_RUN_DEFAULT: esegue il ciclo degli eventi finché il conteggio di riferimento va a zero. Restituisce sempre zero.
  • UV_RUN_ONCE: Sondare per nuovi eventi una volta. Notare che questa funzione si blocca se non ci sono eventi in sospeso. Restituisce zero una volta terminato (nessun handle attivo o richiesta lasciata) o diverso da zero se sono previsti più eventi (il che significa che è necessario eseguire nuovamente il ciclo degli eventi in futuro).
  • UV_RUN_NOWAIT: consente di eseguire il polling dei nuovi eventi una volta ma non bloccare se non ci sono eventi in sospeso.

Si consideri il caso in cui un programma ha un singolo osservatore l'ascolto di una presa di corrente. In questo scenario, verrà creato un evento quando il socket ha ricevuto i dati.

  • UV_RUN_DEFAULT bloccherà il chiamante anche se il socket non ha dati. Il chiamante tornerà da uv_run(), quando:
    • Il ciclo è stato esplicitamente arrestato, tramite uv_stop()
    • Niente più osservatori sono in esecuzione nel ciclo. Ad esempio, l'unico osservatore è stato fermato.
  • UV_RUN_ONCE bloccherà il chiamante anche se il socket non ha dati. Il chiamante tornerà da uv_run(), quando una delle seguenti si verificano:
    • Il ciclo è stato interrotto esplicitamente, tramite uv_stop()
    • Niente più osservatori sono in esecuzione nel ciclo. Ad esempio, l'unico osservatore è stato fermato.
    • Ha gestito un massimo di un evento.Ad esempio, il socket ha ricevuto dati e il callback dell'utente è stato richiamato. Ulteriori eventi potrebbero essere pronti per essere gestiti, ma non verranno gestiti nella chiamata corrente uv_run().
  • UV_RUN_NOWAIT restituirà se il socket non ha dati.

Spesso, in esecuzione di un evento-loop in modo non-blocking è fatto di integrarsi con altri eventi-loops. Considera un'applicazione con due loop di eventi: libuv per il lavoro di backend e Qt UI (che è guidato dal proprio loop di eventi). Essere in grado di eseguire il ciclo degli eventi in modo non bloccante consente a un singolo thread di inviare eventi su entrambi i loop di eventi. Qui è una panoramica semplicistico mostra due libuv loop viene gestita da un unico filo:

uv_loop_t *loop1 = uv_loop_new(); 
uv_loop_t *loop2 = uv_loop_new(); 

// create, initialize, and start a watcher for each loop. 
... 

// Handle two event loops with a single thread. 
while (uv_run(loop1, UV_RUN_NOWAIT) || uv_run(loop2, UV_RUN_NOWAIT)); 

Senza usare UV_RUN_NOWAIT, loop2 sarebbe solo eseguito una volta loop1 o loop1 's osservatori sono stati fermati.

Per ulteriori informazioni, prendere in considerazione la lettura delle sezioni Advanced Event Loops e Processes di An Introduction to libuv.

+1

Questa documentazione (quella in uv.h) è obsoleta e talvolta non accurata. La nuova documentazione è su docs.libuv.org: http://docs.libuv.org/en/v1.x/loop.html#c.uv_run – saghul

Problemi correlati