Actualización:las versiones más recientes del conjunto de tareas tienen un -a
/--all-tasks
opción que "opera en todas las tareas (subprocesos) para un pid dado" y debería resolver el comportamiento que muestro a continuación.
Escribí un script de Python que simplemente activa algunos hilos y quema ciclos de CPU. La idea es probar el conjunto de tareas contra él, ya que es bastante 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()
Solo ejecutar el script de Python consume alrededor del 150 % del uso de la CPU.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Lanzar mi secuencia de comandos de Python con el conjunto de tareas funciona como se esperaba. Ver arriba muestra el proceso de Python vinculado al 100 % de uso.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Curiosamente, iniciar el script de Python y luego usar inmediatamente el conjunto de tareas para establecer la afinidad del proceso recién iniciado limita el proceso al 100 %. Observe en el resultado que el programador de Linux terminó de ejecutar los comandos de Bash antes de generar los subprocesos de Python. Entonces, se inició el proceso de Python, luego se configuró para ejecutarse en la CPU 0, luego generó sus subprocesos, que heredaron la afinidad adecuada.
[~/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
Ese resultado contrasta con este método, que es exactamente el mismo pero permite que los subprocesos de Python se generen antes de establecer la afinidad del proceso de Python. Esto replica los resultados de "el conjunto de tareas no hace nada" que describí anteriormente.
[~/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é va mal aquí?
Aparentemente, los subprocesos generados antes de que se cambie la afinidad del proceso principal no heredan la afinidad de su padre. Si alguien pudiera editar un enlace a la documentación que explica esto, sería útil.
Creo que deberá llamar a taskset una vez por hilo, es decir, use ps -eL
en lugar de pgrep
y canalizar eso a taskset -cp 0
ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0
Esto llama al conjunto de tareas para todos los ID de subprocesos.
prueba numactl con --physcpubind
(o -C
) en cambio. La página del manual dice:
... La política se establece para comando y es heredada por todos sus hijos.
(en versiones recientes de taskset
también hay un -a
opción que Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.
pero no está claro si esto también funciona para los procesos secundarios de una tarea lanzada con taskset
en lugar de modificar un proceso que ya se está ejecutando)