Domanda

Sto cercando di venire con un design per un pool di thread con un sacco di requisiti di progettazione per il mio lavoro.Questo è un problema reale per la lavorazione del software, ed è un compito difficile.Ho un lavoro di implementazione, ma mi piacerebbe buttare a questo e vedere cosa interessante idee la gente può venire con, in modo che io possa confrontare la mia implementazione e vedere come impila in su.Ho cercato di essere il più specifici ai requisiti come posso.

Il pool di thread deve eseguire una serie di compiti.L'attività può essere breve (<1sec) o di lunga esecuzione (ore o giorni).Ogni attività è associata una priorità (da 1 = molto bassa, 5 = molto alta).Le attività possono arrivare in qualsiasi momento, mentre le altre attività in esecuzione, in modo che arrivino il pool di thread deve prenderli e programmare come i thread diventano disponibili.

Il compito prioritario è completamente indipendente dell'attività di lunghezza.Infatti, è impossibile dire quanto tempo un compito potrebbe portare a termine senza l'esecuzione di esso.

Alcune attività sono CPU bound, mentre alcuni sono notevolmente i / o associato.È impossibile sapere in anticipo di ciò che un determinato compito sarebbe (anche se credo che potrebbe essere possibile rilevare durante l'attività in esecuzione).

L'obiettivo primario del pool di thread è quello di massimizzare il throughput.Il pool di thread deve utilizzare in modo efficace le risorse del computer.Idealmente, per la CPU attività, il numero di thread attivi sarebbe uguale al numero di Cpu.Per i / o associato compiti, più thread deve essere allocato che ci sono Cpu in modo che il blocco non eccessivamente influenzare le prestazioni.Ridurre al minimo l'uso di blocchi e l'utilizzo di thread-safe/veloce contenitori è importante.

In generale, si dovrebbe eseguire priorità maggiore attività con una maggiore priorità della CPU (rif:SetThreadPriority).Priorità più bassa compiti non dovrebbe "bloccare" priorità maggiore attività di esecuzione, in modo che se un task a priorità più alta arriva mentre tutte le priorità bassa attività in esecuzione, il task a priorità più alta arriva a eseguire.

I compiti sono un "max l'esecuzione di compiti" parametro associato con loro.Ogni tipo di attività è consentito solo per eseguire questo al più numerose istanze concorrenti del compito alla volta.Per esempio, potremmo avere le seguenti attività in coda:

  • A - 1000 istanze - priorità bassa - max compiti 1
  • B - 1000 istanze - priorità bassa - max compiti 1
  • C - 1000 istanze - priorità bassa - max compiti 1

Un lavoro di attuazione potrà essere eseguito solo (al massimo) 1 A, 1 B e 1 C allo stesso tempo.

Ha bisogno per funzionare su Windows XP, Server 2003, Vista e Server 2008 (ultimo service pack).


Per riferimento, si può usare la seguente interfaccia:

namespace ThreadPool
{
    class Task
    {
    public:
        Task();     
        void run();
    };

    class ThreadPool
    {    
    public:
        ThreadPool();
        ~ThreadPool();

        void run(Task *inst);
        void stop();
    };
}
È stato utile?

Soluzione

Così che cosa stiamo andando a prendere il blocco di costruzione di base per questo.Windows dispone di due edifici che sembrano promettenti :- I/O Porte di Completamento (IOCPs) e Chiamate di Procedura Asincrona (Apc).Entrambi questi ci danno FIFO di accodamento senza dover effettuare esplicita di chiusura, e con una certa quantità di built-in supporto del sistema operativo in luoghi come l'utilità di pianificazione (ad esempio, IOCPs in grado di evitare alcuni di contesto).

Apc sono forse un po ' più in forma, ma noi dovremo essere leggermente attenti con loro, perché non sono abbastanza "trasparente".Se l'elemento di lavoro esegue un'attesa accettabile (::SleepEx, ::WaitForXxxObjectEx, etc.) e abbiamo accidentalmente spedizione un APC, poi, il filo appena inviato APC prendere il filetto, la sospensione in precedenza l'esecuzione di APC fino a quando il nuovo APC è finito.Questo è un male per i nostri requisiti di concorrenza e può fare di overflow dello stack più probabile.

Altri suggerimenti

Ha bisogno per funzionare su Windows XP, Server 2003, Vista e Server 2008 (ultimo service pack).

Che cosa caratteristica del sistema integrato di pool di thread li rendono inadatti per la tua attività?Se si desidera destinazione XP e 2003 non è possibile utilizzare il nuovo shiny Vista/2008 piscine, ma è ancora possibile utilizzare QueueUserWorkItem e amici.

@DrPizza - questa è una domanda molto buona, e uno che colpisce diritto al cuore del problema.Ci sono un paio di motivi perché QueueUserWorkItem e Windows NT pool di thread è stato escluso (anche se la Vista non sembrano più interessanti, forse in pochi anni).

In primo luogo, abbiamo voluto avere maggiore controllo su quando si inizia e si ferma thread.Abbiamo sentito che il NT pool di thread è restio a iniziare un nuovo thread, se pensa che i compiti sono pochi in esecuzione.Potremmo usare la WT_EXECUTELONGFUNCTION, ma abbiamo davvero non hanno idea se l'attività è di lunga o breve

In secondo luogo, se il pool di thread è stato già riempito con una lunga esecuzione, priorità bassa attività, non vi sarebbe alcuna possibilità di un'attività ad alta priorità a farlo girare in maniera tempestiva.Il NT pool di thread non ha un vero concetto di task di priorità, quindi non si può fare un QueueUserWorkItem e dire "oh, a proposito, eseguire questo subito".

In terzo luogo, (in base alle informazioni in lingua inglese) il NT pool di thread non è compatibile con il STA appartamento modello.Non so bene cosa questo significherebbe, ma tutti i nostri thread di lavoro eseguito in una STA.

@DrPizza - questa è una domanda molto buona, e uno che colpisce diritto al cuore del problema.Ci sono un paio di motivi perché QueueUserWorkItem e Windows NT pool di thread è stato escluso (anche se la Vista non sembrano più interessanti, forse in pochi anni).

Sì, sembra che ha molto rafforzato in Vista, abbastanza versatile ora.

OK, sto ancora un po ' poco chiaro su come si desidera che la priorità al lavoro.Se la piscina è attualmente in esecuzione di un'attività di tipo A con la massima concorrenza di 1 e di bassa priorità, e viene data una nuova attività anche di tipo A (e massima concorrenza 1), ma questa volta con un alta priorità, che cosa dovrebbe fare?

La sospensione attualmente in esecuzione è Un peloso (potrebbe contenere un blocco che la nuova attività deve prendere, critico il sistema).Non può generare un secondo thread e basta farlo funzionare insieme (il permesso di concorrenza è solo 1).Ma non è possibile aspettare la priorità bassa, il compito è stato completato, perché il runtime è illimitata, e così facendo permetterebbe una priorità bassa compito di bloccare un'attività ad alta priorità.

La mia presunzione è che è l'ultimo comportamento che si sono dopo?

@DrPizza:

OK, sto ancora un po ' poco chiaro su come si desidera che la priorità al lavoro.Se la piscina è attualmente in esecuzione di un compito di tipo A con la massima concorrenza di 1 e bassa priorità, e viene dato una nuova attività anche di tipo A (massimo concorrenza 1), ma questa volta con un alta priorità, che cosa dovrebbe fare?

Questo è un po ' difficile, anche se in questo caso credo di essere felice con la semplice priorità bassa attività da eseguire per il completamento.Di solito, noi non vedere un sacco di gli stessi tipi di attività con diverse priorità.Nel nostro modello, è possibile fermare in modo sicuro e successive operazioni di riavvio in alcuni punti ben precisi (per motivi diversi rispetto a questo), anche se le complicazioni che questo avrebbe introdotto probabilmente non vale la pena il rischio.

Normalmente, solo diversi tipi di incarichi, hanno priorità diverse.Per esempio:

  • Una task - 1000 istanze - bassa priorità
  • B attività - 1000 casi - ad alta priorità

Supponendo che le mansioni erano venute e sono stati in esecuzione, il B compiti erano arrivati, noi vorremmo che il B attività per essere in grado di eseguire più o meno subito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top