10

独自のプロセスグループでプロセスを開始したい(または、開始後にグループを変更したい)。

  • グループ内のプロセスが端末からCtrl+に応答するようにするC
  • コマンドを使用してグループ内のすべてのプロセスを終了できるように、プロセスグループのIDを取得しますkill

注:試しsetsid prog [args]ましたが、プロセスがターミナルからCtrl + Cに応答せず、新しいプロセスグループIDを取得できませんでした。

setpgrp($pid, $pid)また、Perlとを介してプロセスグループを変更しようとしましたがPOSIX::setpgid($pid, $pid)、役に立ちませんでした。

編集:より大きな問題:

多くの子プロセスを同期的に開始するプロセス(シングルスレッド。「多作」プロセスと呼びましょうP)があります(次々に、前の子プロセスが終了すると新しいプロセスを開始します)。Pターミナルから、その下のプロセスのツリーを強制終了できるようにしたいと思います。Pそのためには、のグループのプロセスを強制終了するように簡単に調整できます。ただし、デフォルトの動作はP、その親プロセスのグループ内にあります。つまり、私が持っていてそのツリーが独自のグループにない限り、グループP内のすべてのプロセスを強制終了すると、親が強制終了されます。PP

P私の意図は、その下の木を殺すことですが、そのP親ではありません。また、Pのコード自体を変更することはできません。

4

3 に答える 3

5

「独自のプロセスグループでプロセスを開始する」とはどういう意味ですか? シェルは、独自のプロセス グループでプロセスを起動します。これは、ジョブ制御を行う方法です (フォアグラウンドでプロセスのプロセス グループを作成し、バックグラウンドで起動するすべてのパイプラインに対していくつかのプロセス グループを作成します)。

シェルがパイプラインごとに新しいプロセス グループを起動することを確認するには、次のようにします。

ps fax -o pid,pgid,cmd | less

次のようなものが表示されます。

11816 11816  |   \_ /bin/bash
4759   4759  |       \_ ps fax -o pid,pgid,cmd
4760   4759  |       \_ less

シェルがパイプライン用の新しいプロセス グループを作成し、パイプライン内のすべてのプロセスがプロセス グループを共有していることに注意してください。

編集:

私はあなたが何を得ているか知っていると思います。systemPerl から呼び出しています。どうやら、sh -cジョブ制御のないシェルであるため、新しいプロセス グループを作成しません。

私がすることはfork、次に子に対して:

setpgrp;
system("ps fax -o pid,pgid,cmd");

そしてwait親に。

于 2011-04-27T20:16:05.103 に答える
1

編集: あなたがしたいことが setsid を使用していたが、結果のプロセスのセッション ID および/または pid を見つけた場合:

setsid コマンドを使用してプロセスを起動すると、端末にアタッチされないため、もちろん ctrl-c には応答しません。

の出力をgrepすることで見つけることができます

ps x -O sid 

または、より限定的なもの

ps x -o %c,%p,sid

または、すべてのエントリの proc/[pid]/stat を単純にトローリングし、セッション ID とその他の関心のあるものを調べます (詳細については、man proc を参照してください)。

setsid の man ページには、出力を直接生成するためのフラグはありませんが、標準を変更することで、目的の情報を出力する独自のバージョンを簡単に作成できます。

たとえば、次の結果の 1 つから setsid.c のコピーを取得します。

http://www.google.com/codesearch?as_q=setsid&as_package=util-linux

nls インクルード、ロケール関連、および問題を引き起こす _("") エラー マクロをコメント アウトし、execvp 行の直前にこれを追加します。

    printf("process will be pid %d sid %d\n", getpid(), getsid(0));
于 2011-04-27T19:19:55.713 に答える
1

上記のninjaljの提案に続くPerlコードの答えは次のとおりです。

prolific_wrapper.pl

my $pid = fork();
if (not defined $pid) {

    die 'resources not available';

} elsif ($pid == 0) {

    # CHILD
    setpgrp;
    exit system(prolific => @ARGV);

} else {

    # PARENT
    my $was_killed = 0;
    local $SIG{INT} = sub {
        say 'kill prolific and its tree ...';
        kill KILL => -$pid;
        $was_killed = 1;
    };
    wait;
    my $child_status = $?;
    $SIG{INT} = 'DEFAULT';
    if ($was_killed) {kill INT => $$}
    else {exit $child_status}

}

どうもありがとうございました!

于 2011-04-28T19:01:21.600 に答える