2010-02-10 4 views
56

Qualcuno sa di un modo per bloccare singoli thread all'interno di un processo Java su core CPU specifici (su Linux)? L'ho fatto in C, ma non riesco a trovare come farlo in Java. Il mio istinto è che questo richiederà una chiamata JNI, ma speravo che qualcuno qui potesse avere qualche intuizione o avrebbe potuto farlo prima.Affinità thread Java

Grazie!

+1

Vedere la mia risposta qui sotto al commento di Hassan. Alcuni thread sono molto intensivi di I/O, altri richiedono un uso intensivo della CPU. Se sto schermando le interruzioni di I/O su un particolare core, mi piacerebbe che i thread di I/O intensivi fossero sui core dello stesso socket, e mi piacerebbe proteggere i thread che consumano la CPU dall'I/O . – Dave

+40

@gimpf: come sempre con questo tipo di "domanda in discussione": SO non riguarda il "perché", riguarda il "come". L'affinità della CPU esiste per una ragione, c'è una ragione per cui esistono utilità sotto Linux e Windows per impostare l'affinità della CPU di un processo. La domanda dell'OP è una domanda perfettamente valida che non vuole "perché" ma un "come". – SyntaxT3rr0r

+6

@WizardOfOdds: Dubito che il "perché" sia vietato su SO, e poiché Java non è di solito il primo linguaggio di programmazione per le modifiche delle prestazioni relative alla concorrenza, penso che un controllo di integrità sia valido. – gimpf

risposta

42

Non è possibile farlo in puro java. Ma se proprio ne hai bisogno, puoi usare JNI per chiamare il codice nativo che fa il lavoro. Questo è il punto di partenza con:

http://ovatman.blogspot.com/2010/02/using-java-jni-to-set-thread-affinity.html

http://blog.toadhead.net/index.php/2011/01/22/cputhread-affinity-in-java/

UPD: Dopo qualche pensiero, ho deciso di creare la mia classe per questo: ThreadAffinity.java E 'basato JNA, e molto semplice - quindi, se vuoi usarlo in produzione, potrebbe essere necessario passare un po 'di tempo per renderlo più stabile, ma per il benchmarking e il testing funziona bene così com'è.

UPD 2: C'è un altro library per lavorare con affinità di thread in java. Si utilizza lo stesso metodo Come notato in precedenza, ma ha un'altra interfaccia

+0

+1 Works! Eccezionale! Nota il commento che ho lasciato nel primo blog - hai bisogno di '#define _GNU_SOURCE' sopra tutti gli include. –

+1

+1: ho trasformato questa funzionalità in una libreria che utilizza JNI o ​​JNA a seconda di ciò che è disponibile. Ha anche un timer a bassa latenza e supporto occupato in attesa con l'istruzione PAUSE ASM. https://github.com/peter-lawrey/Java-Thread-Affinity –

+0

@PeterLawrey È fantastico, grazie! (supponendo che funzioni che devo ancora verificare). Ci sono alcuni problemi con la tua libreria (principalmente la documentazione e un bug), però; come posso contattarti a riguardo? – Raphael

0

IMO, questo non sarà possibile a meno che non si utilizzino chiamate native. JVM dovrebbe essere indipendente dalla piattaforma, qualsiasi chiamata di sistema fatta per raggiungere questo risultato non produrrà un codice portatile.

+6

Non sono preoccupato per la portabilità. – Dave

+5

@questzen: e se la chiamata di sistema viene eseguita solo se viene rilevato che il programma Java viene eseguito su un sistema operativo che supporta tale chiamata? Il codice sarebbe ancora portatile ma semplicemente non imposta alcuna affinità CPU su altri sistemi operativi. Questa è l'unica cosa che mi infastidisce sempre: le persone che urlano "codice non portabile" non appena fai qualche JNI o ​​qualche Runtime.exec(). Ho un programma che fa entrambe le cose e che funzionano su Linux, Windows e OS X. – SyntaxT3rr0r

+0

Non si tratta di utilizzare o meno le chiamate native, ma sapere se la piattaforma supporta questo "out of the box". @questzen ha ragione che la JVM non estrae l'accesso a questo perché non è molto neutrale rispetto alla piattaforma. Potresti riuscire a trovare librerie di terze parti che lo faranno. – PSpeed

0

Non è possibile (almeno con Java normale).

È possibile utilizzare thread pools per limitare la quantità di thread (e quindi di core) utilizzati per diversi tipi di lavoro, ma non è possibile specificare un core da utilizzare.

Esiste anche la (piccola) possibilità che il runtime Java non supporti il ​​threading nativo per il proprio sistema operativo o hardware. In questo caso, vengono utilizzati green threads e verrà utilizzato un solo core per l'intera JVM.

9

So che è passato un po 'di tempo, ma se qualcuno incontra questo thread, ecco come ho risolto questo problema. Ho scritto uno script che avrebbe fatto quanto segue:

  1. "jstack -l"
  2. prendere i risultati, trovare il "nid" s 'dei fili che voglio bloccare manualmente verso il basso per core.
  3. Taskset quei thread.
+1

Per motivi di interesse, ho pensato che il task avesse funzionato solo sui processi e non su singoli thread. Qual è la sintassi per farlo in una discussione? – Matt