2012-05-17 19 views
5

Ho un'applicazione di acquisizione dati in esecuzione su Windows 7, utilizzando VC2010 in C++. Un thread è un heartbeat che invia una modifica ogni 0,2 secondi per mantenere in vita un hardware che ha un timeout di circa 9 secondi. In genere la chiamata del battito cardiaco richiede 10-20 ms e il thread trascorre il resto del tempo dormendo.Posso impostare la priorità di un singolo thread sopra 15 per un normale processo con priorità?

Occasionalmente, tuttavia, ci sarà un ritardo di 1-2 secondi e l'hardware si spegnerà momentaneamente. Il thread heartbeat è in esecuzione a THREAD_PRIORITY_TIME_CRITICAL che è 15 per un processo con priorità normale. I miei altri thread sono in esecuzione con priorità normale, anche se utilizzo una DLL per controllare un altro hardware e ho notato con Process Explorer che avvia diversi thread eseguiti al livello 15.

Non riesco a rintracciare la fonte del lento verso il basso ma altri nella mia applicazione stanno vedendo lo stesso tipo di ritardi quando ciò accade. Ho apportato diverse ottimizzazioni al codice heartbeat anche se è abbastanza semplice, ma i guasti occasionali si verificano ancora. Ora mi chiedo se posso aumentare la priorità di questo thread oltre i 15 senza specificare REALTIME_PRIORITY_CLASS per l'intero processo. In caso contrario, ci sono dei lati negativi che dovrei sapere di usare REALTIME_PRIORITY_CLASS? (Oltre a questo thread heartbeat, il resto dell'applicazione non ha necessità temporali in tempo reale.)

(Oppure qualcuno ha qualche idea su come rintracciare questi rallentamenti ... non è sicuro se la fonte potrebbe essere nella mia app o da qualche altra parte nel sistema).

Update: Quindi non avevo effettivamente provato il passaggio 31 nella mia chiamata AfxBeginThread e risulta ignora tale valore e imposta il filo alla normalità la priorità al posto dei 15 che ottengo con THREAD_PRIORITY_TIME_CRITICAL.

Aggiornamento: risulta che l'esecuzione dell'utilità di deframmentazione dischi è un buon metodo per causare numerosi ritardi dei thread. Anche l'esecuzione del processo su REALTIME_PRIORITY_CLASS e il thread heartbeat su THREAD_PRIORITY_TIME_CRITICAL (livello 31) non sembrano essere d'aiuto. La prossima cosa da provare è chiamare AvSetMmThreadCharacteristics ("Pro Audio")

Aggiornamento: programmare il thread heartbeat come "Pro Audio" funziona per aumentare la priorità del thread oltre 15 (Base = 1, Dynamic = 24) ma non lo fa sembrano fare davvero la differenza quando la deframmentazione è in esecuzione. Sono stato in grado di correlare molti dei rallentamenti con l'utilità di deframmentazione del disco in modo da disattivare la scansione settimanale. Non riesco ancora a spiegare alcuni ritardi, quindi aumenteremo fino a un timeout del watchdog di 5-10 secondi.

+6

mi fa paura quando le persone usano parole come "battito cardiaco" e "chiuso per motivi di sicurezza" in una questione di programmazione su Windows . :) Non è certamente un RTOS: http://en.wikipedia.org/wiki/Real-time_operating_system – HostileFork

+2

Penso che il tuo cane da guardia sia severo. Su un RTOS i 500 ms sono molti, ma su Windows qualsiasi cosa al di sotto dei 15 secondi è rischioso. Se hai il controllo sul tuo cane da guardia allora ti suggerisco di prolungare il timeout o farlo spegnere solo se manca un certo numero di trigger. – Fozi

+0

Domanda: Qual è il tempo dopo il quale l'hardware si spegne? – Fozi

risposta

4

Anche se fosse possibile, aumentare la priorità non aiuterà. Il thread eseguibile con la priorità più alta ottiene il processore in ogni momento.

Molto probabilmente c'è un processo di interrupt esteso che si verifica quando gli interrupt sono disabilitati. Gli interrupt funzionano in modo efficace con una priorità più alta rispetto a qualsiasi thread.

Potrebbe essere video, rete, disco, seriale, USB, ecc., Ecc. Occorrerà qualche informazione per disabilitare in modo selettivo o utilizzare un driver alternativo per vedere se l'esitazione del sistema problema è influenzata. Una volta che lo trovi, quindi cercare un modo per prevenirlo potrebbe variare da banale a impossibile a seconda di cosa sia.

Senza ulteriore conoscenza del sistema, è difficile dirlo. Hai provato a eseguirlo su un diverso PC?

+0

grazie per il voto di fiducia :) Ho eseguito su alcuni computer diversi, ma generalmente ho sempre lo stesso software e driver installati. Penserò a ciò che posso disabilitare ed eseguire, ma sarà difficile rintracciare poiché il problema è intermittente, sembra che accada ogni giorno o due. Grazie! – jacobsee

+0

la ragione per cui spero possa fare la differenza è che questa altra dll hardware ha 5 su 7 del thread al livello 15. Quando le cose si danno da fare preferisco che il mio thread abbia la priorità su di loro. Tuttavia se si tratta di un interrupt hardware come suggerisci che non sarebbe di aiuto. – jacobsee

0

Vorrei provare a utilizzare CreateWaitableTimer() & SetWaitableTimer() e verificare se sono soggetti agli stessi problemi di prelazione.

1

Ufficialmente non è possibile utilizzare thread REALTIME in un processo che non ha REALTIME_PRIORITY_CLASS.

Unoficially si potrebbe giocare con la non documentata NtSetInformationThread vedi: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtSetInformationThread.html

Ma visto che non ho provato, non ho più informazioni su questo.

D'altra parte, come è stato detto prima, non si può mai essere sicuri che il sistema operativo non impiegherà più tempo quando il quantum del thread scadrà. Alcuni driver scritti male sono spesso la causa di tale latenza.

altrimenti c'è un software che può dire se si è comportato male parti del kernel: http://www.thesycon.de/deu/latency_check.shtml

+0

il controllo della latenza sembra utile - grazie! – jacobsee

+0

Se trovi un caso in cui la latenza del DPC aumenterà drasticamente, le priorità del thread non possono aiutarti poiché i DPC (Delayed Procedure Calls) funzionano a "priorità" più elevata (in realtà IRQL) rispetto a qualsiasi altro in modalità utente ... – Jaka

Problemi correlati