2010-04-07 14 views
11

Come si dice allo scheduler di thread in linux di non interrompere il thread per nessun motivo? Sto programmando in modalità utente. Semplicemente bloccando un mutex compila questo? Voglio impedire che altri thread nel mio processo vengano programmati quando una determinata funzione è in esecuzione. Bloccherebbero e sprecerei cicli di CPU con interruttori di contesto. Voglio che qualsiasi thread che esegue la funzione sia in grado di terminare l'esecuzione senza interruzioni anche se viene superato il timeslice dei thread.impedisce che il thread di linux venga interrotto dallo scheduler

+0

Ciao grazie per tutti i commenti. Penso di aver imparato la risposta, che è NO. La ragione per cui ho chiesto è stata: La nostra app impiega molto tempo negli stati di attesa IO perché accede a 500 GB di file di dati che cambiano ogni ora. Voglio usare molti thread per eseguire IO in parallelo (sì, i filer possono gestirli ... stanno già gestendo IO da 3200 istanze di app e questo non è per gestire più lavoro, ma per abbreviare il tempo di wall). Le nostre scatole sono tutte MP con 8-64 "CPU" che contano nuclei effettivi e hyperthreading ... quindi posso avere un sacco di thread in esecuzione simultaneamente. – johnnycrash

+0

I/O paralleli di solito riducono le prestazioni, può essere piuttosto considerevole. Un'unità non può fare cose in parallelo (oltre un certo punto a seconda della configurazione del raid). Se si desidera massimizzare le prestazioni, è necessario un numero limitato di thread I/O che alimentino (il più grande possibile) i dati da/per i thread di lavoro. – leeeroy

+0

Cerca in aio.h. Uscita in ingresso asincrona @leeeroy Parallell IO può essere una vittoria poiché consente all'utilità di pianificazione dei blocchi di avere effettivamente delle cose da pianificare e utilizzare meglio le spazzole delle testine di lettura/scrittura del disco. Le unità Plus dispongono di una propria cache e eseguono la propria pianificazione. Ad ogni modo, AIO dovrebbe ottenere anche questo beneficio. – nategoose

risposta

8

Come si dice allo scheduler di thread in Linux di non interrompere il thread per nessun motivo?

Non si può davvero fare, è necessario un sistema in tempo reale per questo. La cosa che si chiude con Linux è impostare la politica di pianificazione su un programmatore in tempo reale, ad es. SCHED_FIFO e imposta anche l'attributo PTHREAD_EXPLICIT_SCHED. Vedi per es. here, anche adesso, ad es. i gestori di irq e altre cose interromperanno il thread ed eseguiranno.

Tuttavia, se ci si preoccupa solo che i thread nel proprio processo non siano in grado di fare nulla, allora sì, averli bloccati su un mutex il thread in esecuzione è sufficiente.

La parte difficile è quella di coordinare tutti gli altri thread per afferrare quel mutex ogni volta che il thread deve fare la sua cosa.

+0

in modo basilare è un gruppo di thread di lavoro e una coda di lavoro. In questo momento non ho quasi nessun blocco da quando preparo il lavoro e poi sparo i fili. Per la fase 2 voglio aumentare il parallelismo facendo in modo che i thread aggiungano più lavoro alla coda mentre vanno. Per fare ciò, i thread devono controllare un archivio dati comune per vedere se i dati esistono. Dati inesistenti = il lavoro per la coda. È questa funzione che controlla l'archivio di dati comune che temo possa essere utilizzato molto. Penso di aver solo bisogno di rendere la parte che richiede assolutamente un piccolo extra con una riscrittura. – johnnycrash

+0

Ho usato questo http://asgaard.homelinux.org/svn/threadqueue/ per fare cose simili. Spegni il no. dei thread di lavoro che si desidera e li alimentano tramite il threadqueue, che blocca e attende finché non vengono aggiunti dati alla coda.se non si hanno più thread di lavoro di quanti ne possiedi, la contesa tra loro dovrebbe essere minima. – nos

1

Non è possibile. Se potessi, cosa impedirebbe al tuo thread di non rilasciare mai la richiesta e far morire di fame altri thread.

Il meglio che puoi fare è impostare la priorità dei thread in modo che lo scheduler preferisca i thread con priorità più bassa.

+0

Dang. La priorità del thread è un problema, a meno che non possa cambiarlo quando inserisco la funzione e poi diminuisco quando esco. Inoltre, che cosa costerebbe in termini di cicli. I thread di lavoro sono quelli di cui mi sto preoccupando e ce ne saranno molti. – johnnycrash

1

Perché non lasciare che i thread in competizione si blocchino, quindi lo scheduler non avrà più nulla da programmare se non il filo conduttore? Perché complicare la progettazione secondo indovinare lo scheduler?

+0

Beh, stavo pensando che se il thread A ha bloccato una risorsa verso la fine del timeslice del thread A, allora potrebbe essere anticipata. Lo scheduler quindi passerebbe in rassegna tutti gli altri thread di lavoro, diciamo che ce ne sono 50. Poiché questa funzione è altamente probabile che venga colpita, ciascuno dei 50 thread potrebbe essere eseguito per un breve periodo, quindi bloccare. Quindi immagino di avere solo 50 interruttori di contesto a causa del programma di pianificazione preventiva. Rifiuti inutili. – johnnycrash

2

Si dovrebbe progettare il proprio sw in modo che tu sia non dipendente dallo scheduler che fa la cosa "giusta" dal punto di vista della tua app. Lo scheduler è complicato. Farà ciò che pensa sia meglio.

Gli interruttori di contesto sono economici. Tu dici

Sarei sprecare cicli di CPU con interruttori di contesto.

ma non si dovrebbe guardare in questo modo. Utilizzare i macchinari multi-threaded di mutex e processi bloccati/in attesa. I macchinari sono pronti per l'uso ...

+0

Sì, sono d'accordo. Non voglio reinventare la ruota. Voglio solo sapere come usare la ruota al massimo. Ho letto da qualche parte che un mutex può essere bloccato e sbloccato nell'ordine di migliaia di volte al secondo. Quello è troppo lento per quello di cui ho bisogno. Hai ragione riguardo all'architettura. Purtroppo ho 20 anni di codice, quindi il mio primo piano era provare qualcosa che funzionasse con cambiamenti minimi. Quindi domande sulla prelazione. Inoltre, usa memmap molto. La mia ipotesi è chiamata memoc malloc a pezzi di 4k. Potrei avere 64 memmap simultanee che succedono tutte volendo malloc 50 volte ciascuna. – johnnycrash

+0

Bene, mmap non chiama malloc, avrà problemi con le pagine di memoria nel kernel. Inoltre, quante migliaia/sec è troppo lento? Il blocco/sblocco di un mutex senza contesa può essere fatto nell'ordine di molti milioni/sec, quando c'è contesa e i thread devono bloccarsi, tuttavia diventa più lento. – nos

+0

@Larry K Potresti fornire supporto per l'affermazione "gli switch di contesto sono economici"? – Bacon

1

Cerca nella pianificazione in tempo reale sotto Linux. Non l'ho mai fatto, ma se lo fai davvero, questo è il più vicino possibile nel codice dell'applicazione utente.

Quello di cui sembri aver paura non è davvero un grosso problema. Non è possibile impedire al kernel di interrompere i programmi per interrupt reali o di attività con priorità più alta che si desidera eseguire, ma con la normale pianificazione il kernel usa il proprio valore di priorità calcolato che praticamente gestisce la maggior parte di ciò di cui si è preoccupati. Se il thread A tiene in esclusiva la risorsa X (X potrebbe essere un blocco) e il thread B sta aspettando che la risorsa X diventi disponibile, allora la priorità effettiva di A sarà almeno pari alla priorità di B. Tiene anche conto se un processo sta consumando molta CPU o se sta trascorrendo molto tempo a dormire per calcolare la priorità. Naturalmente, il buon valore va anche lì.

+0

Grazie. Non sono preoccupato per il kernel che mi precede, solo altri thread nel mio processo. Quindi quel tipo di interruzioni sarebbe ok. Un'interruzione per consentire l'esecuzione di un altro thread nel mio processo è ciò di cui sono preoccupato. – johnnycrash

+0

Le parole che stai usando non sembrano corrispondere a quello che vuoi, e non sono sicuro che quello che vuoi sia ciò che vuoi veramente. Potresti volere un multithreading cooperativo o potresti volere qualcos'altro. Intendi dire che mentre il thread A mantiene il blocco X, nessun altro thread che vuole il blocco X può essere eseguito, perché questo è praticamente ciò per cui sono tutte le cose per la sincronizzazione dei thread. Devi solo progettare il tuo codice correttamente; chiamare e rilasciare le serrature al momento giusto/luogo. Se si intende che quando il thread A mantiene il blocco X, nessun altro thread può eseguire tutto ciò che si deve cercare in SIGSTOP – nategoose

Problemi correlati