hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

tasksetコマンドの使い方



1 tasksetコマンドとは?

指定したCPUでプロセスを起動したり、動作中のプロセスが使用しているCPUを変更したりすることができるコマンドです。

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

仮想マシンの搭載CPU数を確認します。搭載CPU数は4個であることがわかります。

[root@server ~]# cat /proc/cpuinfo |grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3

3 インストール方法

util-linuxパッケージをインストールします。

[root@server ~]# yum -y install util-linux

tasksetコマンドの版数を確認します。

[root@server ~]# taskset --version
taskset from util-linux 2.23.2

4 オプション一覧

[root@server ~]# taskset -h
使い方: taskset [オプション] [mask | cpu-list] [pid|cmd [引数...]]

Options:
 -a, --all-tasks         operate on all the tasks (threads) for a given pid
 -p, --pid               operate on existing given pid
 -c, --cpu-list          display and specify cpus in list format
 -h, --help              display this help
 -V, --version           output version information

The default behavior is to run a new command:
    taskset 03 sshd -b 1024
You can retrieve the mask of an existing task:
    taskset -p 700
Or set it:
    taskset -p 03 700
List format uses a comma-separated list instead of a mask:
    taskset -pc 0,3,7-11 700
Ranges in list format can take a stride argument:
    e.g. 0-31:2 is equivalent to mask 0x55555555

詳細情報は、taskset(1) を確認してください。

5 指定したCPUでプロセスを起動する方法

tasksetコマンドの書式は以下のとおりです。

# taskset -c X <コマンド>
    (*) XはCPUの番号(0,1,2...)を指定する。

5.1 単一CPUでプロセスを起動する方法

stressプロセスをCPU0で起動してみます。 なお、stressコマンドの使い方はstressコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# taskset -c 0 stress -c 1 -q &
[1] 4415

psコマンドを使って、プロセスが使用しているCPUを確認します。 stressの親プロセス、子プロセスともにCPU0を使用していることがわかります。 また親プロセスはdo_waitカーネル関数を呼び出してスリープしています。 do_waitカーネル関数はwaitシステムコールの延長で呼び出されるカーネル関数です。 そのため、CPU使用率は0%となっています。 一方、子プロセスはCPU使用率が100%になっています。 psコマンドの使い方はこちらを参照してください。 なお、WCHANでカーネル関数を表示するには、kernel-debuginfoパッケージをインストールする必要があります。

[root@server ~]# ps -C stress -o comm,pid,ppid,psr,%cpu,wchan
COMMAND            PID   PPID PSR %CPU WCHAN
stress            4415   2146   0  0.0 do_wait
stress            4416   4415   0  100 -

このとき、子プロセスが何をしているか確認します。 まず、straceを使ってどのようなシステムコールを実行しているか確認します。 straceの実行結果が出力されないので、システムコールを実行していないことがわかります。 なお、straceコマンドの使い方は、straceコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# strace -p 4416
strace: Process 4416 attached

次に、ltraceを実行します。stressプロセスはrand関数を実行していることがわかります。 ltraceはプロセスが実行する関数(glibc等)を出力するコマンドです。 なお、システムコールと関数は次の点で全く違います。 システムコールを実行すると、プロセスがユーザモードとカーネルモードを切り替えて動作しますが、 関数を実行すると、プロセスはユーザモードだけで動作します。

[root@server ~]# ltrace -p 4416
rand()                                                                    = 1174652688
rand()                                                                    = 1686559875
rand()                                                                    = 938217751

なお、rand関数のパラメータが空白になっていますが、(多分)glibcのdebuginfoパッケージをインストールするとパラメータが表示されると思います。

5.2 指定した複数CPUでプロセスを起動する方法

複数CPUでプロセスを起動する書式は以下のようになります。

# taskset -c X,Y,Z... <コマンド>
    (*) X,Y,ZはCPUの番号(0,1,2...)を指定する。

stressプロセスをCPU0,2で動作させてみます。

[root@server ~]# taskset -c 0,2 stress -c 1 -q &
[1] 7741

psコマンドを使って、プロセスが動作しているCPUを確認します。 stressの親プロセスがCPU0、子プロセスがCPU2で動作していることがわかります。

[root@server ~]# ps -C stress -o comm,pid,ppid,psr,wchan
COMMAND            PID   PPID PSR WCHAN
stress            7741   6329   0 do_wait
stress            7742   7741   2 -

後始末をします。

[root@server ~]# pkill stress
[1]+  Terminated              taskset -c 0,2 stress -c 1 -q

6 動作中プロセスが使用しているCPUを変更する方法

stressコマンドを実行して、stressプロセスを4つ生成します。 生成するプロセスはrand()を繰り返し実行し、ユーザ空間のCPU使用率が100%程度になります。

[root@server ~]# stress -c 4 -q&
[1] 8137

psコマンドを使って、プロセスが動作しているCPUを確認します。 stressの親プロセスがCPU1,子プロセスがCPU0,1,2,3でそれぞれ動作していることがわかります。

[root@server ~]# ps -C stress -o comm,pid,ppid,psr,wchan
COMMAND            PID   PPID PSR WCHAN
stress            8137   6329   1 do_wait  ★親プロセス
stress            8138   8137   2 -              ★子プロセス
stress            8139   8137   1 -              ★子プロセス
stress            8140   8137   0 -              ★子プロセス
stress            8141   8137   3 -              ★子プロセス

子プロセス(PID=8138)をCPU2からCPU0で動作するように変更してみます。

[root@server ~]# taskset -pc 0 8138
pid 8138's current affinity list: 0-3
pid 8138's new affinity list: 0

psコマンドを使って、プロセスが動作しているCPUを確認します。 子プロセス(PID=8138)がCPU2からCPU0に移動したことがわかります(★印)。

[root@server ~]# ps -C stress -o comm,pid,ppid,psr,wchan
COMMAND            PID   PPID PSR WCHAN
stress            8137   6329   1 do_wait
stress            8138   8137   0 - ★
stress            8139   8137   1 -
stress            8140   8137   2 -
stress            8141   8137   3 -

後始末をします。

[root@server ~]# pkill stress
[1]+  Terminated              stress -c 4 -q

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。 Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ