Pembaruan:Versi kumpulan tugas yang lebih baru memiliki -a
/--all-tasks
opsi yang "beroperasi pada semua tugas (utas) untuk pid tertentu" dan harus menyelesaikan perilaku yang saya tunjukkan di bawah.
Saya menulis skrip Python yang hanya memutar beberapa utas dan membakar siklus CPU. Idenya adalah untuk menguji kumpulan tugas terhadapnya, karena cukup sederhana.
#!/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()
Hanya menjalankan skrip Python menghabiskan sekitar 150% penggunaan CPU.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Meluncurkan skrip Python saya dengan kumpulan tugas berfungsi seperti yang diharapkan. Menonton bagian atas menunjukkan proses Python yang dipatok pada penggunaan 100%.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Menariknya, meluncurkan skrip Python dan kemudian segera menggunakan kumpulan tugas untuk menyetel afinitas proses yang baru dimulai membatasi proses pada 100%. Perhatikan dari output bahwa penjadwal Linux selesai mengeksekusi perintah Bash sebelum menelurkan utas Python. Jadi, proses Python dimulai, lalu disetel untuk berjalan di CPU 0, lalu menelurkan utasnya, yang mewarisi afinitas yang tepat.
[~/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
Hasil itu kontras dengan metode ini, yang persis sama tetapi memungkinkan utas Python muncul sebelum menyetel afinitas proses Python. Ini mereplikasi hasil "set tugas tidak melakukan apa-apa" yang saya jelaskan di atas.
[~/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
Apa yang salah di sini?
Rupanya utas yang muncul sebelum afinitas proses induk diubah tidak mewarisi afinitas induknya. Jika seseorang dapat mengedit tautan ke dokumentasi yang menjelaskan hal ini, itu akan sangat membantu.
Saya pikir Anda harus memanggil kumpulan tugas sekali per utas, yaitu gunakan ps -eL
bukannya pgrep
dan kirimkan ke taskset -cp 0
ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0
Ini memanggil set tugas untuk semua id utas.
coba numactl dengan --physcpubind
(atau -C
) alih-alih. Halaman manual mengatakan:
... Kebijakan ditetapkan untuk perintah dan diwarisi oleh semua turunannya.
(dalam versi taskset
terbaru ada juga -a
opsi yang Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.
tetapi tidak jelas apakah ini juga berfungsi untuk proses turunan dari tugas yang diluncurkan dengan taskset
sebagai lawan dari memodifikasi proses yang sudah berjalan)