In generale, c'è ben poco che puoi fare qualsiasi cosa con le informazioni raccolte da un'attività. Il motivo è questo: una volta che avvii un'attività, devi lasciarla finire, non importa quale.
- Non puoi sospenderlo per sempre. Alcune altre parti del codice potrebbero dipendere dal risultato dell'attività; sospenderlo significa che il codice dipendente aspetterà per sempre.
- Non puoi ucciderlo. L'attività potrebbe aver apportato modifiche nel file system o nel database; potrebbe lasciare il sistema o il datastore in uno stato incoerente se si uccide l'attività nel mezzo dell'esecuzione.
- Per lo stesso motivo per cui non puoi ucciderlo, non puoi nemmeno spostare un'attività in esecuzione su un altro computer o persino su un altro thread.
Fondamentalmente, una volta che un compito è in esecuzione, devi lasciarlo finire, indipendentemente dalle molte risorse necessarie.
L'unica altra azione correttiva che puoi eseguire è che se vedi un numero significativo di thread worker sono:
- Esecuzione di alcune attività;
- Non consumano molto tempo della CPU a causa del fatto che sono bloccati (bloccando I / O)
Quindi puoi forse creare qualche altro thread di lavoro e dare loro nuovi compiti, nella speranza che alcuni di essi siano intensivi della CPU e quindi recuperare i "cicli di CPU sprecati".
Alcuni progetti di pool di thread tentano semplicemente di aumentare opportunisticamente il numero di thread di lavoro (e di eseguirli simultaneamente nelle attività) fino al punto in cui visualizzano rendimenti marginali decrescenti.
link
Posso solo dare una panoramica approssimativa delle idee. Il feedback è benvenuto.
In primo luogo, alcune definizioni.
-
"CPU intensive" - attività che, una volta avviato l'esecuzione su un thread, continueranno ad essere eseguite sulla CPU fino al termine, facendo progressi continui lungo il percorso e raramente si offriranno volontariamente per una "pausa" (operazione di blocco ).
-
"IO intensive" - attività che, durante la sua esecuzione su un thread, tendono a richiedere frequentemente una "pausa" (inserimento in sleep o un'operazione di blocco) volontariamente. Questa "pausa" si verifica in genere quando l'attività è in attesa di un evento esterno, ad esempio in attesa che i dati leggano un file o da una query del database.
-
"CPU wasting" - attività che in apparenza assomigliano al tipo "CPU intensive", ma sono in effetti "busy-spinning" - eseguono un ciclo vuoto stretto senza fare progressi. Potrebbe essere ulteriormente suddiviso in "errori di programmazione (difetto software)" o "carico di lavoro dannoso".
Avviso Uso la parola "volontario" più volte. Ciò è dovuto al fatto che un sistema operativo può sospendere preventivamente un thread mentre passa al contesto in altri thread in modo che il sistema operativo possa supportare un numero totale di thread in eccesso eccessivo rispetto al numero di core della CPU. (I core della CPU tipici sono a una cifra o a dieci bassi, ma il numero totale tipico di thread nel sistema operativo è compreso tra centinaia e migliaia).
È possibile che un thread watchdog (con i privilegi amministrativi appropriati) richieda il sistema operativo per il tempo CPU consumato da ogni thread di lavoro. Questo può essere usato per decidere come "CPU intensive" è una particolare attività in esecuzione.
Inoltre, potrebbe essere possibile che il thread del watchdog si riattivi con un intervallo regolare per verificare quale sia il thread di ciascun worker. Se si vuole scoprire se un thread trascorre la maggior parte del proprio tempo a essere bloccato (in attesa di I / O), sarà necessario eseguire il drill down del motivo della sospensione del thread. Come descritto in precedenza, è necessario distinguere tra i thread che sono preventivati dal sistema operativo, rispetto ai thread che sono bloccati dalle proprie operazioni IO. Questo è fattibile su alcuni sistemi operativi, ma potrebbe essere impossibile su altri sistemi operativi.
Non ho mai usato nessuna di queste tecniche quindi non so quanto siano praticabili o efficaci queste tecniche.