次のような状況があります: (以下の関数は Python から取得したものです)
実行中のプロセス A があり、それに cgroup メモリ制限が設定されています。
os.fork()を使ってAから子プロセスをフォークします。これをBと呼びます。次に、os.execvpを実行してB内にシェルスクリプトをロードします。http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/exec.htmlこのプロセスは、呼び出し元 (つまり B) と同じアドレス空間で実行されます。
Bで実行されるシェルスクリプトは、指定されたヒープサイズで無期限に実行され、OOM時に自動的に終了するJavaプログラムを作成します。これは、-XX:OnOutOfMemoryError='kill -9 %p'java コマンドに追加します。これにより、B の子として別のプロセス C が作成されます。
上から見ると、予想どおり、B は A の子、C は B の子であることがわかります。
疑問点は以下の通りです。
cgroup 制限は A のみに適用されますか、それとも (A+B) または (A+B+C) に適用されますか?
メモリ制限に達した場合、どのプロセスがすべて強制終了されますか: A、(A+B)、(A+B+C)? また、その理由は? 制限が適用されているプロセスのプロセス PID またはアドレス空間を使用して識別されますか?
上記の点において、すべてのプロセスが強制終了されるわけではない場合、そのような場合には孤立したプロセスが残ってしまうため、cgroup 設定を微調整してすべての子プロセスも強制終了する方法はありますか?
私は基盤となるオペレーティング システムとして Centos7 を使用しています。
答え1
それぞれの質問にお答えします。
- cgroup は A と A のすべての子孫に適用されます。この動作を確認するために実験することができます。次の点を考慮してください。
Create a new memory cgroup
# mkdir /sys/fs/cgroup/memory/example
Note the shell's PID:
# echo $$
679
Put the running shell into the new cgroup
# echo $$ > /sys/fs/cgroup/memory/example/cgroup.procs
Examine what processes are in the cgroup. Here 679 was the
shell's PID; 723 is the pid of cat
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
723
Start a new shell and note its PID
# bash
# echo $$
726
Examine what processes are in the cgroup. 679 was the original
shell. 726 is the second shell. 731 is cat:
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
726
731
cgroup が制限を超えると、まず cgroup からメモリを回収して、cgroup がアクセスした新しいページ用のスペースを確保しようとします。回収が失敗した場合は、OOM ルーチンが呼び出され、cgroup 内で最も大きなタスクを選択して強制終了します。
これに基づいて、cgroup 内のすべてのプロセスが強制終了されるのではなく、最も多くのメモリを消費しているプロセスが選択されます。
- ここで尋ねられていることに合わせて、どのプロセスを強制終了するかを調整する方法はわかりません。OOMキラーを制御する方法はあります。たとえば、これを参照してください。Linux Weekly News記事ただし、親プロセスの 1 つが強制終了された場合、その子プロセスはすべて PID = 1 (デフォルト) のプロセスに再親化されます。