Quale modello parallelo usare?

6

Ho bisogno di scrivere un'applicazione server che recuperi la posta da diversi server di posta / caselle di posta e quindi deve elaborare / analizzare questi messaggi. Tradizionalmente, avrei fatto questo multi-thread, avviando un thread per il recupero dei messaggi (o forse uno per cassetta postale) e poi elaborando i messaggi.

Ci stiamo spostando sempre più verso server in cui abbiamo 8+ core, quindi mi piacerebbe utilizzare questi core il più possibile (e non usare 1 al 100% e lasciare intatti gli altri sette). Quindi concettualmente, ad esempio, sarebbe bello poter scrivere l'applicazione in modo tale che due core siano "ininterrottamente" in grado di recuperare e-mail e che quattro core siano "ininterrottamente" elaborati / analizzando le e-mail (poiché l'elaborazione e l'analisi delle mail è più Intensivo della CPU rispetto al recupero della posta).

Questo sembra un buon concetto, ma dopo aver studiato alcuni modelli paralleli, non sono sicuro di come sia meglio implementarlo. Nessuno dei modelli è davvero adatto. Sto lavorando in VS2012, nativo C ++, ma credo che dal punto di vista del design questo non sia importante e solo alcuni suggerimenti su come organizzare questo sarebbe fantastico!

    
posta Wim Van Houts 11.07.2013 - 21:42
fonte

1 risposta

3

Il modello attore della concorrenza sembra essere adatto per questo.

Il modello

Nel caso in cui non si abbia familiarità con questo modello, questo è il seguente:

Gli attori sono thread che girano in loop. Ogni attore ha una coda messaggi produttore-consumatore; codice esterno e altri attori comunicano con un attore inviandogli un messaggio (accodandolo nella coda dei messaggi).

Il thread di un attore bloccherà l'attesa di un messaggio nella sua coda di messaggi, e quando uno apparirà l'attore lo tratterà, quindi tornerà indietro per elaborare o attendere il prossimo messaggio. Ripeti.

Nota: Gli "attori" sono a volte chiamati "agenti", ma quel termine è applicato in modo scorretto. Vedere il thread dei commenti qui sotto per ulteriori informazioni.

Architettura

Potresti creare attori appositamente per scaricare i messaggi (ad esempio uno per mailserver / casella di posta) e altri attori per l'elaborazione dei messaggi di posta elettronica una volta scaricati.

Collegando i due si poteva avere un singolo agente di routing che avrebbe ricevuto riferimenti ai file di posta scaricati dagli attori di recupero e invierebbe ciascun riferimento a un attore di elaborazione disponibile o ne creava un altro per elaborarlo se tutti gli altri attori di elaborazione erano occupati Quando un attore di elaborazione ha terminato l'elaborazione, invia un messaggio all'attore di routing dicendo che è stato fatto in modo che l'attore di routing possa sapere che potrebbe inviare un altro messaggio ad esso per elaborare.

Scommetto che a questo punto c'è una libreria per gli attori per C ++ [ UPDATE: vedi il commento di @rwong sotto]. Se tutto il resto fallisce potresti provare Erlang;)

Non sono sicuro di come funzionano le librerie di threading C ++, se mappano i thread su un singolo core o su più core, ma se non lo fa per te potresti prendere lo stesso concetto e invece di usare i thread farli essere processi discreti e utilizzare una sorta di struttura di passaggio dei messaggi per la comunicazione.

Modifica: Scommetto che avrai un collo di bottiglia in rete, quindi, potrebbe non avere senso voler occupare tutti i core contemporaneamente (a meno che l'elaborazione non tempo moooolto).

Modifica: risposta espansa e terminologia corretta (agente - > attore)

    
risposta data 11.07.2013 - 22:04
fonte