プロセスの子孫

プロセスの子孫

プロセスコンテナを構築しようとしています。コンテナは他のプログラムを起動します。たとえば、バックグラウンドジョブを実行するbashスクリプトを起動するには、「&」を使用します。

私が求める重要な機能は、コンテナを終了するときにコンテナの下に作成されたすべてのアイテムを終了する必要があることです。直系の子どもだけでなく、その子孫も同じだ。

このプロジェクトを開始したときにプロセスを終了すると、そのサブプロセスも自動的に終了すると誤って信じていました。同じ誤解を持っている方に助言を求めました。シグナルを捉えて子供に殺人を伝えることは可能ですが、私がここで欲しいのはそれではありません。

私はxtermを閉じたときにxtermで実行されているすべてがnohup'dでない限り終了するので、私が達成したいことが達成可能であると信じています。これには孤児プロセスが含まれます。それが私が再現したかったのです。

私が探しているのがUnixセッションに関連しているという考えがあります。

プロセス内のすべての子孫を識別する信頼できる方法がある場合は、任意の信号をその子孫に送信できることも便利です。例えばSIGUSR1。

答え1

プロセスにシグナルを送信すると、プロセスは終了します。あるプロセスを終了すると、他のプロセスも終了するという噂がどのように始まったのか疑問に思います。特に直観にずれているようです。

ただし、複数のプロセスを終了する方法があります。ただし、プロセスに信号を送信することはありません。全部殺せるプロセスグループ-1234に信号を送信します。ここで、1234はプロセスグループリーダーのPIDであるプロセスグループID(PGID)です。実行するとき管路、パイプライン全体はプロセスグループで始まります(アプリケーションは次を呼び出してそれを変更できます)。setpgidまたはsetpgrp)。

foo &バックグラウンドでプロセスを開始すると、()そのプロセスは独自のプロセスグループに属します。プロセスグループは、端末へのアクセスを管理するために使用されます。通常、フォアグラウンドプロセスグループのみが端末にアクセスできます。バックグラウンド操作は変更されません。会議ただし、セッション全体を終了したり、セッションのプロセスグループやプロセスを列挙したりするツールがないため、あまり役に立ちません。

端末を閉じると、カーネルは信号を送信します。SIGHUP自分のもので持っているすべてのプロセスに制御端子。これらのプロセス会話をするただし、すべてのセッションに制御端末があるわけではありません。したがって、プロジェクトの1つの可能性は、次のように実行して、独自の端末ですべてのプロセスを開始することです。スクリプト画面待つ。ターミナルエミュレータプロセスを終了して埋め込みプロセスを終了します(まだ接続されていないと仮定)。setsid)。

他の操作を行わない独自のユーザーとしてプロセスを実行して、より多くの分離を提供できます。これにより、すべてのプロセスを簡単に終了できます。実行kill(システムコールまたは便利)を対応するユーザーとして指定し、-1をPIDパラメータとして終了します。これは、「このユーザーに対するすべてのプロセス」を意味します。

実際の環境で含まれているプロセスを実行すると、より多くの分離を提供できますが、より多くの設定が必要です。コンテナ

答え2

プロセスのすべての子孫を識別する信頼性の高い方法は、pstree <pid>pidが親プロセスIDであるコマンドを使用することです。

マニュアルページを読むpstree ここ

プロセスグループのすべてのメンバーにシグナルを送信します。killpg(<pgrp>, <sig>);
ここで、pgrpはプロセスグループ番号、sigはシグナルです。

指定されたプロセスグループの子プロセスを待ちます。waitpid(-<pgrp>, &status, ...);

現在実行中のタスクの代替方法は、新しいbashシェルでプロセスコンテナを実行することです。このコマンドを使用して新しいbashシェルを作成し、bashプロセスを実行します。すべてのプロセスを終了するには、コマンドを使用してシェルを終了しますexit

答え3

親スクリプトで終了信号を取得し、すべての子プロセスを終了させる。例えば、

#!/bin/bash
# kill the parent and children together
trap "kill 0" EXIT
# create all the children
for n in $(seq 1 100)
do
    ( echo "begin $n"; sleep 60; echo "end $n" ) &
done
# wait for the children to complete
wait

答え4

使用

unshare -fp --kill-child -- yourprogram

キルすると、unshareすべての子プロセス(yourprogram作成された可能性があります)が終了します。

これでutil-linuxを介して可能になります2.32私はこれをアップストリームで実装しました。。ユーザーの名前空間(カーネル構成オプションCONFIG_USER_NS=y)またはroot権限が必要です。また、見ることができますここ

関連情報