更新:新しいバージョンのタスクセットには -a
があります /--all-tasks
「指定された pid のすべてのタスク (スレッド) で動作する」オプションであり、以下に示す動作を解決する必要があります。
私は単純にいくつかのスレッドを起動して CPU サイクルを消費する Python スクリプトを作成しました。これは非常に単純なので、それに対して taskset をテストするという考えです。
#!/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()
Python スクリプトを実行するだけで、約 150% の CPU 使用率が消費されます。
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
タスクセットを使用して Python スクリプトを起動すると、期待どおりに動作します。上を見ると、Python プロセスの使用率が 100% に固定されていることがわかります。
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
興味深いことに、Python スクリプトを起動してすぐにタスクセットを使用して、開始したばかりのプロセスのアフィニティを設定すると、プロセスは 100% に制限されます。出力から、Linux スケジューラーが Python スレッドを生成する前に Bash コマンドの実行を終了したことに注意してください。そのため、Python プロセスが開始され、CPU 0 で実行するように設定され、スレッドが生成され、適切なアフィニティが継承されました。
[~/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
この結果は、この方法とは対照的です。この方法はまったく同じですが、Python プロセスのアフィニティを設定する前に Python スレッドを生成できます。これは、上で説明した「タスクセットが何もしない」結果を複製します。
[~/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
<ブロック引用> 何が問題なのですか?
親プロセスのアフィニティが変更される前に生成されたスレッドは、親プロセスのアフィニティを継承しないようです。誰かがこれを説明するドキュメントへのリンクを編集できれば、それは役に立ちます.
スレッドごとに 1 回タスクセットを呼び出す必要があると思います。つまり、ps -eL
を使用します。 pgrep
の代わりに それを taskset -cp 0
にパイプします
ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0
これにより、すべてのスレッド ID のタスク セットが呼び出されます。
--physcpubind
で numactl を試してください (または -C
) 代わりは。 manページには次のように書かれています:
... ポリシーはコマンドに設定され、そのすべての子に継承されます。
(最近のバージョンの taskset
では -a
もあります オプション which Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.
ただし、これが taskset
で起動されたタスクの子プロセスでも機能するかどうかは明らかではありません すでに実行中のプロセスを変更するのではなく)