2010-01-18 12 views
7

Qualcuno può aiutarmi a rispondere alle domande su epoll_wait.prestazioni epoll

  1. E 'eccessivo usare tanti fili che epoll_wait chiamata sulla stessa FDS impostate per servire a circa 100K socket attivi? o sarà sufficiente creare solo 1 thread per eseguire epoll_wait?

  2. Quanti thread si riavviano da epoll_wait quando, per esempio, un solo socket è pronto per leggere i dati? Voglio dire, può esserci una situazione in cui 2 o più thread si sveglieranno da epoll_wait ma avranno gli stessi fds negli eventi risultanti?

  3. Qual è il modo migliore per organizzare i thread nel server che funziona con molti client attivi (ad esempio 50K +). Il modo migliore è: 1 Thread di I/O Worker che esegue le operazioni di epoll_wait e i/o. + Molti thread di elaborazione dati che elaborano i dati ricevuti dal thread di I/O worker (può impiegare molto tempo, ad esempio qualsiasi logica di gioco) e compongono nuovi dati per il thread di I/O worker da inviare al client. Ho ragione in questo approccio o qualcuno può aiutarmi a trovare il modo migliore per organizzarlo?

Grazie in anticipo, Valentin

risposta

7
  1. Quando si utilizza epoll, si desidera dimensioni vostro totale filo al numero di core della CPU fisiche (o unità di invio hyperthread) che si desidera utilizzare per l'elaborazione. Usare solo un thread per lavoro significa che al massimo un core sarà attivo alla volta.

  2. Dipende dalla modalità del descrittore del file epoll. Gli eventi possono essere "edge triggered", vale a dire che avvengono solo una volta atomicamente, o "level triggered" che significa che ogni chiamante riceve un evento se c'è spazio nel buffer.

  3. Informazioni insufficienti da dire. Suggerirei di non avere thread per scopi speciali, per semplicità, e semplicemente di gestire il "comando" di ciascun evento nel thread in cui è stato ricevuto. Ma ovviamente ciò dipende dalla natura della tua applicazione.

+0

Quindi, se ho capito correttamente, lo schema migliore appare nel modo seguente: Creare il numero di thread I/O uguale al numero di core nel sistema e utilizzare ET epoll_wait. Ogni thread avrà il proprio sottoinsieme di fd. Ad esempio 4 thread per il processore IC2Q. Ogni thread gestisce connessioni 25K e in totale 100K. E la prossima domanda: Devo avere un thread separato che soddisfi il socket del listener epoll_wait e gestirlo in quale sottoinsieme del socket appena accettato dell'ID verrà aggiunto?Ed è thread-safe per aggiungere fd appena accettato usando epoll_ctl in un thread, mentre altri sta facendo epoll_wait su questo sottoinsieme? – Valentin

+0

Attenderei su tutti i descrittori in tutti i thread, in realtà. A meno che tu non sappia che puoi vincere sugli effetti della cache isolando il lavoro correlato su specifiche CPU, di solito è una perdita fare questo tipo di partizionamento. Finisci per affamare una CPU mentre un'altra ancora ha lavoro che potrebbe essere fatto. E sì: le operazioni di epoll sono atomiche (anche se ovviamente dovrai bloccare tu stesso le tue impostazioni personali). –

+0

Come si comporterebbe ET epoll_wait? Tutti i thread risveglieranno da epoll_wait? O solo 1 filo? Se ho capito correttamente ET epoll_wait è atomico e accadrà solo una volta per i file pronti. Ad esempio: ho 2 fds e 2 thread in attesa su epoll_wait. 1 fd diventa pronto e solo 1 thread verrà ripreso e se altri fd saranno pronti durante i primi thread sul primo fd, il secondo thread verrà ripreso. Andy, è corretto? – Valentin

-1

In realtà questo è un caso di utilizzo errato di epoll.

Non è assolutamente necessario condividere epoll fd tra i thread. Altrimenti si ha la possibilità che un thread legga parte dei dati in arrivo su un fd e un altro thread sullo stesso file fd senza alcun modo per sapere quale parte dei dati era prima dell'altro.

Basta chiamare epoll_create in ogni thread che chiama epoll_wait. Altrimenti l'I/O è rotto.

+0

Mi sembra che tu stia confondendo l'ef fd con la fd del socket attuale. L'utilizzo di epoll su più thread è assolutamente possibile, infatti, è uno dei punti di utilizzo. Per non avere una condizione di competizione tra i thread, è necessario utilizzare 'EPOLLONESHOT' o, nei kernel più recenti,' EPOLLEXCLUSIVE'. [Questo grande blog] (https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/) spiega i dettagli. – kralyk