Aktualisierung:Neuere Versionen von Taskset haben einen -a
/--all-tasks
Option, die "alle Tasks (Threads) für eine bestimmte PID verarbeitet" und das unten gezeigte Verhalten lösen sollte.
Ich habe ein Python-Skript geschrieben, das einfach einige Threads hochfährt und CPU-Zyklen verbrennt. Die Idee ist, das Taskset dagegen zu testen, da es ziemlich einfach ist.
#!/usr/bin/env python
import threading
def cycle_burner():
while True:
meh = 84908230489 % 323422
for i in range(3):
thread = threading.Thread(target=cycle_burner)
print "Starting a thread"
thread.start()
Allein das Ausführen des Python-Skripts verbraucht etwa 150 % der CPU-Auslastung.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Das Starten meines Python-Skripts mit Taskset funktioniert wie erwartet. Oben zu sehen zeigt den Python-Prozess, der auf 100 % Nutzung festgelegt ist.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Interessanterweise begrenzt das Starten des Python-Skripts und das sofortige Verwenden von taskset zum Festlegen der Affinität des gerade gestarteten Prozesses den Prozess auf 100 %. Beachten Sie in der Ausgabe, dass der Linux-Scheduler die Ausführung der Bash-Befehle abgeschlossen hat, bevor er die Python-Threads erstellt hat. Also wurde der Python-Prozess gestartet, dann wurde er so eingestellt, dass er auf CPU 0 läuft, dann hat er seine Threads erzeugt, die die richtige Affinität geerbt haben.
[~/cbench]$ ./burn_cycles.py &; taskset -pc 0 `pgrep python`
[1] 8561
pid 8561's current affinity list: 0-3
pid 8561's new affinity list: 0
Starting a thread
[~/cbench]$ Starting a thread
Starting a thread
Dieses Ergebnis steht im Gegensatz zu dieser Methode, die genau die gleiche ist, aber es den Python-Threads ermöglicht, zu spawnen, bevor die Affinität des Python-Prozesses festgelegt wird. Dies repliziert die oben beschriebenen "Taskset tut nichts"-Ergebnisse.
[~/cbench]$ ./burn_cycles.py &
[1] 8996
[~/cbench]$ Starting a thread
Starting a thread
Starting a thread
[~/cbench]$ taskset -pc 0 `pgrep python`
pid 8996's current affinity list: 0-3
pid 8996's new affinity list: 0
Was läuft hier falsch?
Anscheinend erben Threads, die erzeugt werden, bevor die Affinität des übergeordneten Prozesses geändert wird, nicht die Affinität ihres übergeordneten Prozesses. Wenn jemand einen Link zu einer Dokumentation einfügen könnte, die dies erklärt, wäre das hilfreich.
Ich denke, Sie müssen taskset einmal pro Thread aufrufen, dh ps -eL
verwenden statt pgrep
und leiten Sie das an taskset -cp 0
weiter
ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0
Dies ruft den Aufgabensatz für alle Thread-IDs auf.
versuchen Sie numactl mit --physcpubind
(oder -C
) stattdessen. Die Manpage sagt:
... Die Richtlinie wird für den Befehl festgelegt und von allen ihren untergeordneten Elementen geerbt.
(in neueren Versionen von taskset
es gibt auch einen -a
Option welche Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.
aber es ist nicht klar, ob dies auch für Tochterprozesse einer Aufgabe funktioniert, die mit taskset
gestartet wurde im Gegensatz zur Änderung eines bereits laufenden Prozesses)