プロセスが存在するcgroupへスレッドコントローラを登録
スレッド化サブツリーを作る方法はもう1つあります。
この方法では次の2つの手順が必要です。いずれも同じcgroupに対して操作を行います。
- "domain"タイプであるcgroupでスレッドコントローラ有効にし,
その子cgroupでもスレッドコントローラを有効にする (該当cgroupとその親cgroup両方の cgroup.
にスレッドコントローラが登録された状態)subtree_ controll - プロセスをcgroupに登録する
この手順の順番はどちらが先でも問題ありません。この結果は次のようになります。
- 該当のcgroupは"domain threaded"なcgroupとなる
- 上記の"domain threaded"なcgroup配下の"domain" cgroupは"domain invalid"となる
cgroup v2の当初の仕様では,
試してみましょう。
まずは先ほどの例と同様のツリーを作成します。そしてtd
の親cgroupcgroup.
ファイルにcpuコントローラを登録します。cgroupでコントローラを有効化するあたりのお話は連載の第38回をご覧ください。
# mkdir -p td/th{01,02}
# tree -d .
.
└── td
├── th01
└── th02
3 directories
# echo "+cpu" > cgroup.subtree_control
# cat cgroup.subtree_control
cpu
# cat td/cgroup.controllers
cpu (tdでcpuコントローラが有効になった)
そしてcgroup td
にプロセスを登録します。
# echo $$ > td/cgroup.procs # cat td/cgroup.procs 912 938 # cat td/cgroup.type domain
この時点ではまだcgroup td
のタイプは"domain"です
ここでtd
のcgroup.
ファイルにCPUコントローラを登録し,td
の子孫cgroupでCPUコントローラが使えるようにしてみます。
# echo "+cpu" > td/cgroup.subtree_control # cat td/cgroup.subtree_control cpu # cat td/th{01,02}/cgroup.controllers cpu cpu
td
のcgroup.
ファイルにCPUコントローラが登録され,th01
,th02
のcgroup.
ファイルにはcpu
が登録されており,
ここでおもむろにtd
のcgroup.
ファイルを確認して,td
のcgroupタイプを確認してみましょう。
# cat td/cgroup.type domain threaded
プロセスが所属し,td
はdomain threadedになっています。その子cgroupであるth01
,th02
のタイプを確認してみましょう。
# cat td/th{01,02}/cgroup.type domain invalid domain invalid
親となるtd
が"domain threaded"となったので,th01
,th02
はいずれも"domain invalid"となっています。スレッド化サブツリーを完成させるには,
# echo "threaded" > td/th01/cgroup.type # echo "threaded" > td/th02/cgroup.type # cat td/th{01,02}/cgroup.type threaded threaded
th01
,th02
がthreadedに設定されました。これでスレッド化サブツリーの完成です。
cgroup.
ファイルへの書き込みでスレッド化サブツリーを作成した際の例と同様にスレッドを登録してみましょう。
# pstree -p 928 threadtest(928)─┬─{threadtest}(929) └─{threadtest}(930) # echo 928 > /sys/fs/cgroup/td/cgroup.procs # echo 929 > /sys/fs/cgroup/td/th01/cgroup.threads # echo 930 > /sys/fs/cgroup/td/th02/cgroup.threads (プロセスとスレッドを同一スレッド化サブツリーのそれぞれ別々のcgroupに登録) # cat /sys/fs/cgroup/td/cgroup.procs 893 928 (←登録できている) 939 # cat /sys/fs/cgroup/td/th01/cgroup.threads 929 (←登録できている) # cat /sys/fs/cgroup/td/th02/cgroup.threads 930 (←登録できている)
親プロセスのPIDとそのプロセスに所属するスレッドが,
cgroup.threads
ファイルへのタスクの登録権限
第40回で,
今回の実行例では,root
権限で操作を行っていますので,
つまり,cgroup.
ファイルへの書き込みには第40回で説明した,
- 書き込む先の
cgroup.
ファイルへの書き込み権threads - 移動元と移動先のcgroupの共通の祖先にある
cgroup.
ファイルへの書き込み権procs
そして,
- 移動元と移動先のcgroupは同じスレッド化サブツリー内に所属している必要がある
という条件が加わります。
root cgroupの扱い
これまでの例では,
では,
root直下にth01
というcgroupを作成し,
# mkdir /sys/fs/cgroup/th01 # cd /sys/fs/cgroup/ # echo threaded > th01/cgroup.type (root直下のth01をthreadedに変更する) # cat th01/cgroup.type threaded (threadedに変更された)
このth01
に,
# pstree -p 902 threadtest(902)─┬─{threadtest}(903) └─{threadtest}(904) # echo 902 > th01/cgroup.procs (マルチスレッドプロセスをth01に登録) # cat th01/cgroup.threads 902 903 904 (プロセス内のタスクがすべて登録された)
このように何の問題もなく登録できました。つまりroot直下に"threaded" cgroupを作成できるということです。
ここでスレッドを1つrootに移動してみましょう。
# echo 904 > /sys/fs/cgroup/cgroup.threads (スレッドの1つをrootに移動) # grep 904 cgroup.threads 904 (rootに移動した) # cat th01/cgroup.threads 902 903 (th01には残りのタスクが残っている)
移動したスレッドだけがrootに移動し,th01
cgroupに残っています。
つまり,
root cgroupは"domain"と"threaded"なcgroupの親になります。このようにroot cgroupを例外的に扱っているのは,
もし"threaded"に変化したroot直下のcgroupが子cgroupを持っていた場合は,
# mkdir -p th02/th03 (2階層のcgroupを作成する) # echo threaded > th02/cgroup.type (親cgroupをthreadedに変更する) # cat th02/cgroup.type threaded # cat th02/th03/cgroup.type domain invalid (子cgroupはdomain invalidに変化する)
まとめ
今回はスレッド化サブツリーの操作について説明をしました。
スレッド化サブツリーを作成するには2つの方法がありました。
cgroup.
ファイルにtype threaded
という文字列を書き込む- プロセスが存在するcgroupへスレッドコントローラーを登録する
そして,
今回でcgroup v2のスレッドモードの説明は終わりです。前回と今回の説明で,