2012-05-11 16 views
11

Sto creando un daemon basato su TCP per la pre/post-elaborazione delle richieste HTTP. I client si collegheranno ad Apache HTTPD (o IIS) e un modulo Apache/IIS personalizzato inoltrerà richieste al mio daemon TCP per un'ulteriore elaborazione. Il mio demone dovrà aumentare (ma non uscire) per gestire un traffico significativo e la maggior parte delle richieste sarà di piccole dimensioni e di breve durata. Il demone sarà costruito in C++ e deve essere multipiattaforma.Server TCP con boost :: asio, scalabilità del pool di thread e coroutine stackless

Attualmente sto esaminando le librerie asio boost, che sembrano una scelta naturale. Tuttavia, ho difficoltà a comprendere i vantaggi del modello di poolless threadless coroutine vs thread. Nello specifico, sto guardando l'esempio del server HTTP n. 3 e l'esempio del server HTTP n. 4 qui: http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/examples.html

Nonostante tutto il mio google, non riesco a comprendere appieno i meriti del server coroutine senza stack e come sarebbe eseguire relativamente al server del pool di thread su un sistema multi-core.

Quale dei due è più adatto alle mie esigenze e perché? Per favore, sentiti libero di 'mollare' le tue risposte riguardo l'idea di coroutine senza pila, sono ancora su un terreno instabile qui. Grazie!

Edit: Un altro caso pensiero/preoccupazione per la discussione: Boost server HTTP esempio # 4 è descritto come "un server HTTP a thread singolo implementato utilizzando coroutine stackless". OK, quindi è interamente single-threaded (giusto? Anche dopo il processo genitore 'fork' a un bambino? Vedere server.cpp nell'esempio # 4) ... il thread singolo diventerà un collo di bottiglia su un sistema multi-core? Suppongo che qualsiasi operazione di blocco impedirà l'esecuzione di tutte le altre richieste. Se questo è davvero il caso, per massimizzare il throughput sto pensando ad un evento asincrono di ricezione dati basato su coroutine, un pool di thread per le mie attività di blocco interno (per sfruttare i multi core), e quindi un meccanismo di connessione chiusa di invio asincrono &. Ancora una volta, la scalabilità è fondamentale. qualche idea?

+0

* Domanda *: Penso di aver capito "per aumentare". Cosa è "scalare"? –

+0

Alcune persone trovano più semplice l'approccio co-routine da leggere/implementare perché il codice viene letto dall'alto verso il basso. Si adattano meglio allo streaming del parsing perché non devi preoccuparti di riprendere da dove avevi interrotto una volta che hai iniziato a consumare di nuovo lo stream dopo un'interruzione nell'input. – avid

+0

@avid - grazie, ho visto nell'esempio del server HTTP di boost n. 4 come l'hanno fatto con il parser della richiesta. È molto bello, senza dubbio, ma sono più interessato alle prestazioni che alla facilità di codifica/implementazione. Cosa ne pensi di questo? – Tom

risposta

9

Ho recentemente esaminato la scalabilità di boost.asio su macchine multi-core. La conclusione principale finora è che essa introduce in testa, contesa dei blocchi e cambi di contesto aggiuntive (almeno su Linux), vedere alcuni dei miei post del blog su questi argomenti:

ho anche iniziato un thread sulla mailing list ASIO per controllare che non ho perso nulla ovvio, vedere http://comments.gmane.org/gmane.comp.lib.boost.asio.user/5133

Se le preoccupazioni principali sono le prestazioni e la scalabilità poi sono Afra id, che non esiste una risposta chiara - potresti dover fare qualche prototipazione e guardare la performance.

Se si dispone di operazioni di blocco, si consiglia di utilizzare più thread. D'altra parte, il cambio di contesto e il conflitto di blocco possono ridurre le prestazioni con più thread (almeno sarà necessario prestare molta attenzione).

Modifica: solo per chiarire la roba senza coroutines: è essenzialmente solo un po 'di zucchero sintattico per rendere l'API asincrona un po' più simile alle chiamate sequenziali/di blocco.

+0

Grazie per aver condiviso la tua esperienza, cercherò di approfondire il tuo blog e codice di esempio mentre costruisco il mio server. Ottimo thread ASIO. Sembra che dovrò semplicemente confrontare alcune implementazioni diverse e procedere da lì. Ehi qualcuno nel tuo thread ASIO ha chiesto se hai utilizzato le funzioni di coroutine, ma non hai visto una risposta. Hai intenzione di delineare questo? Grazie per l'aiuto! – Tom

+0

Come hai capito con i tuoi benchmark e analisi Tom? Sono curioso di vedere dove sei arrivato perché sto giocando anche con questo. – Homer6

+0

@ Homer6 - Ho re-architettato la mia app dopo aver confermato che l'esempio di potenziamento n. 4 era effettivamente limitato a un singolo core. Anche se non lo era, nel mio caso aveva più senso correre all'interno del thread del web server, piuttosto che creare il mio pool personale. Quindi, almeno per ora, ho abbandonato l'idea, e non l'ho perseguita ulteriormente. Scusa, non posso esserti di maggior aiuto! – Tom

0

È necessario misurare gli effetti per essere certi che cosa realmente accadere a causa della difficoltà di prevedere gli effetti relativi di località di riferimento, istruzioni della CPU la cache, i ritardi di programmazione, ecc

Se si desidera una supposizione euristica , considera che l'uso di n. thread con stack size S ognuno prende sempre nS byte tuttavia gran parte dello spazio di stack effettivamente utilizzato da ciascun thread. Se questo ti spinge oltre il confine della pagina, potrebbe diminuire le prestazioni in modo misurabile.

+0

Grazie Mike, suppongo che sto chiedendo più di un teorico "le coroutine più impilate sono più performanti dei pool di thread?" O sto confondendo erroneamente due concetti separati? – Tom

+0

@ Tom: Se utilizzi Windows, scegli l'opzione con il cambio di thread minimo. Le coroutine accuratamente scritte risentiranno di un minor affaticamento della cache nella mia esperienza. Se blocchi per lunghi periodi di tempo, il thrashing è meno significativo. – JimR

+0

@JimR: grazie per il suggerimento. Ho intenzione di indirizzare sia Windows che * nix, quindi il tuo consiglio è gradito – Tom

Problemi correlati