Mise à jour :les versions plus récentes de l'ensemble de tâches ont un -a
/--all-tasks
option qui "fonctionne sur toutes les tâches (threads) pour un pid donné" et devrait résoudre le comportement que je montre ci-dessous.
J'ai écrit un script Python qui fait simplement tourner des threads et brûle des cycles CPU. L'idée est de tester l'ensemble de tâches par rapport à lui, car c'est assez simple.
#!/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()
Le simple fait d'exécuter le script Python consomme environ 150 % de l'utilisation du processeur.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Le lancement de mon script Python avec l'ensemble de tâches fonctionne comme prévu. Regarder en haut montre le processus Python indexé à 100 % d'utilisation.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Fait intéressant, le lancement du script Python, puis l'utilisation immédiate de l'ensemble de tâches pour définir l'affinité du processus qui vient de démarrer plafonne le processus à 100 %. Notez à partir de la sortie que le planificateur Linux a terminé l'exécution des commandes Bash avant de générer les threads Python. Ainsi, le processus Python a été démarré, puis il a été configuré pour s'exécuter sur le CPU 0, puis il a engendré ses threads, qui ont hérité de l'affinité appropriée.
[~/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
Ce résultat contraste avec cette méthode, qui est exactement la même mais permet aux threads Python de se reproduire avant de définir l'affinité du processus Python. Cela reproduit les résultats "l'ensemble de tâches ne fait rien" que j'ai décrits ci-dessus.
[~/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
Qu'est-ce qui ne va pas ici ?
Apparemment, les threads créés avant que l'affinité du processus parent ne soit modifiée n'héritent pas de l'affinité de leur parent. Si quelqu'un pouvait modifier un lien vers la documentation qui explique cela, ce serait utile.
Je pense que vous devrez appeler l'ensemble de tâches une fois par thread, c'est-à-dire utiliser ps -eL
au lieu de pgrep
et dirigez-le vers taskset -cp 0
ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0
Cela appelle l'ensemble de tâches pour tous les identifiants de thread.
essayez numactl avec --physcpubind
(ou -C
) Au lieu. La page de manuel indique :
... La stratégie est définie pour la commande et héritée par tous ses enfants.
(dans les versions récentes de taskset
il y a aussi un -a
option qui Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.
mais il n'est pas clair si cela fonctionne également pour les processus filles d'une tâche lancée avec taskset
au lieu de modifier un processus déjà en cours d'exécution)