問題タブ [process-group]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - 独自のプロセスグループでプロセスを開始するにはどうすればよいですか?
独自のプロセスグループでプロセスを開始したい(または、開始後にグループを変更したい)。
- グループ内のプロセスが端末から
Ctrl
+に応答するようにするC
- コマンドを使用してグループ内のすべてのプロセスを終了できるように、プロセスグループのIDを取得します
kill
。
注:試しsetsid prog [args]
ましたが、プロセスがターミナルからCtrl + Cに応答せず、新しいプロセスグループIDを取得できませんでした。
setpgrp($pid, $pid)
また、Perlとを介してプロセスグループを変更しようとしましたがPOSIX::setpgid($pid, $pid)
、役に立ちませんでした。
編集:より大きな問題:
多くの子プロセスを同期的に開始するプロセス(シングルスレッド。「多作」プロセスと呼びましょうP
)があります(次々に、前の子プロセスが終了すると新しいプロセスを開始します)。P
ターミナルから、その下のプロセスのツリーを強制終了できるようにしたいと思います。P
そのためには、のグループのプロセスを強制終了するように簡単に調整できます。ただし、デフォルトの動作はP
、その親プロセスのグループ内にあります。つまり、私が持っていてそのツリーが独自のグループにない限り、グループP
内のすべてのプロセスを強制終了すると、親が強制終了されます。P
P
P
私の意図は、その下の木を殺すことですが、そのP
親ではありません。また、P
のコード自体を変更することはできません。
linux - シェルスクリプトのプロセスグループの設定方法
シェルスクリプトのプロセスグループを設定するには? また、すべての子プロセスを同じプロセスグループに入れたい
C の setpgid() に似たものを期待しています。
c - Linuxでは、プロセスグループIDをプロセスに再割り当てできますか?
pidX
がプロセスグループリーダーであり、X
終了したが、プロセスグループ内の他のプロセスは(X
pgidとして)実行されたままであるとします。X
Linuxは、値がpidとして新しいプロセスに割り当てられるのを防ぎますか?
POSIXが許可する障害状態のためにこれを尋ねますsetsid
:
[EPERM]呼び出し元のプロセスがすでにプロセスグループリーダーであるか、呼び出し元のプロセス以外のプロセスのプロセスグループIDが呼び出し元のプロセスのプロセスIDと一致しています。
このエラーは、「ランダムに」トリガーされるプロセスグループ(つまりシェル)を使用するコードの回復不能な状態のようであり、さらに厄介なものになります。健全なレベルの品質を目指す実装ではX
、まだpgidとして使用されている間は、pidとしての再割り当てを回避できると思いますが、これはどこにも文書化されていません。
c - プロセスをバックグラウンドに送信し、制御をシェルに戻す
CS クラスのシェルをプログラミングしていますが、ユーザーが「&」文字を渡すと、プロジェクトの一部でプロセスがバックグラウンドで実行されます。
プロセスがフォアグラウンドで実行されている場合、プロセスは単にフォアグラウンドにexecvp
あるため、端末の制御下に置かれます。ただし、バックグラウンド プロセスの場合は、プロセスの実行を開始した後でメイン シェルに制御を戻す必要があります。システムコールtcsetpgrp(pid_t)
が引数として渡されたプロセスをフォアグラウンドに配置することは理解していますが、その使用方法がよくわかりません。
バックグラウンド プロセスの場合、後で呼び出す必要がありますtcsetpgrp
か? execvp
もしそうなら、呼び出すだけでシェルの pid を取得できgetpid
ますか?
c++ - ライブラリの子プロセスのプロセス グループ
私は、クライアント コードに統合されるライブラリ (C++) に取り組んでいます。この lib はいくつかの子プロセスを生成し、(何らかの理由で) 死ぬとすぐにそれらを再生成するためにそれらを監視する必要があります。これらの子プロセスを生成するには、vfork と exec を使用する必要があります。
シグナル ハンドラーを使用して SIGCHLD を処理し、waitpid を呼び出して、どの子が死んでいるかを検出する必要があることはわかっています。ただし、ユーザー コードは同じ考え方を使用して、独自の子プロセスを処理している可能性があります。
waitpid を呼び出すと、停止した可能性のあるすべての子プロセスに関する情報が取得されます (私のものかどうかに関係なく)。死にゆくプロセスが私のものなら、問題ありません... 幸せなケースです。ただし、それがユーザーからのものである場合、既に waitpid を呼び出しているため、ユーザーはそれに関する情報を取得していません。
どうすればそれを回避できますか?
私の最初のアイデアは、プロセス グループを使用することです。初めて fork すると、子 pid を取得して、プロセス グループ ID として保存します。私が作成する各子は、そのグループをこの pid に設定します。皆さん、それは良い選択だと思いますか? (私はそれに問題があります)。
私の 2 番目のアイデアは、シグナル ハンドラーを元のハンドラーにリセットする (または単に呼び出す) ことです。シグナルを再発生させると、元のハンドラーがそれを取得できるようになります。その後、シグナルハンドラを再インストールする必要があります。それは良い選択でしょうか?
3 つ目の選択肢は、INFO (拡張シグナル ハンドラー) を使用することです。瀕死のプロセスの pid は info 構造体で利用できると思います。これが私の子供の 1 人なら、そのために waitpid を呼び出しますが、それで問題ありません。それが私のものでない場合は、元のシグナルハンドラーを呼び出します。それは良い選択でしょうか?
最後に 1 つだけ補足質問をします。元のシグナル ハンドラーを呼び出せるようにするには、常にそれらを復元してシグナルを再生成する必要がありますか、それとも関数呼び出しとして呼び出すだけで十分ですか?
どうもありがとうございました。
linux - Linux OS で 1 つのプロセス グループの pid を取得する方法
Linux pid について 1 つ質問があります。1つの同じグループでpidを取得するには? Linux では「ps」コマンドですべての pid または pgid を取得するのは簡単に思えますが、同じグループに属する pid を取得する方法、つまり同じプログラムの pid を取得する方法を教えてください。誰でもこれについて助けてください。ありがとうございました!
shell - 孤立したプロセスグループでインタラクティブシェルは何をすべきですか?
簡単な質問は、シェルが tty を所有していない孤立したプロセス グループにある場合、シェルは何をすべきかということです。しかし、面白いので、長い質問を読むことをお勧めします。
お気に入りのシェルを使用して、ラップトップをポータブル スペース ヒーターに変える楽しくエキサイティングな方法を次に示します (ただし、tcsh の変人でない限り)。
これにより、bash は CPU を 100% に固定します。zsh と fish は同じことを行いますが、ksh と tcsh はジョブ制御についてつぶやいてからキールオーバーします。ああ、それはプラットフォームにとらわれない攻撃者です。OS X と Linux の両方が影響を受けます。
私の (間違っている可能性がある) 説明は次のとおりですtcgetpgrp(0) != getpgrp()
。したがって、それ自体を停止しようとします: killpg(getpgrp(), SIGTTIN)
. しかし、親 (C プログラム) がリーダーであり、死亡したため、そのプロセス グループは孤立し、孤立したプロセス グループに送信された SIGTTIN はドロップされます (そうしないと、プロセス グループを再び開始することはできません)。したがって、子シェルは停止されませんが、まだバックグラウンドにあるため、すべてがすぐに再実行されます。すすいで繰り返します。
私の質問は、コマンド ライン シェルがこのシナリオをどのように検出できるのか、そしてそれが行うべき正しいことは何なのかということです。私の考えでは、シェルはread
stdin から試行し、read が EIO を与えると終了します。
ご感想ありがとうございます!
編集: /dev/tty で長さゼロの read() を実行しようとしましたが、成功しました。これは悪いことです。EIO を取得するには、/dev/tty からデータを読み取る準備をしておく必要があります。
編集:私が持っていた別の考えはkill(getpgrp(), 0)
. プロセス グループが孤立している場合、これは常に失敗すると思います。ただし、セッション リーダーに通知する権限がないため、失敗することもあります。
編集:後でこれを見つけた人のために、私がやったことはhttps://github.com/fish-shell/fish-shell/issues/422で説明されています。また、将来はどうですか?
linux - 外部プログラムの生成時に setpgid/setsid を呼び出す
コードから外部プログラムを実行する場合、次の 3 つのオプションがあります。
- の後は何もしないでください
fork()
。外部プログラムは、その親のプロセス グループになります。 - などを呼び出し
setpgid(0, 0)
て、外部プログラムが独自のプロセス グループを取得するようにします。 setsid()
また、外部プログラムをその親の制御 tty から分離します。
上記の行動のうち、どの状況で正しいのはどれですか?
たとえば、vim と gnome-open を使用すると、おかしな動作が見られます。
- を実行する
:!gnome-open somefile.pdf
と、PDF ビューアが起動し、すぐに戻ります。 - 次に、たとえば を実行し、
:!cat
cat の実行中にSIGQUIT
using を送信しCTRL-\
ます。
PDF ビューアがクラッシュします。これは、vim と gnome-open の両方が独自のプロセス グループでサブプロセスを生成しているように見えるために発生します。
バグと呼ぶには曖昧すぎるかもしれませんが、それでも誰のせいなのか疑問に思います: vim または gnome-open がsetpgid
fork 後に呼び出されない理由はありますか? シェルが行うように? 起動元の端末から X アプリケーションを分離する代わりにgnome-open
を呼び出す方が理にかなっているでしょうか? setsid
(GLib がそのようなことを行うための標準的なクロスプラットフォームの方法を提供していないのは奇妙だと思います。)
c - すべての子プロセスに SIGTERM を送信しますが、親には送信しません
シグナルに応答して動作する C プログラムがあります。一部のシグナルにより、親がフォークします。これにより、親がシグナルに応答し続けている間、他の処理が可能になります。
親に SIGTERM が送信されたら、分岐した子にも SIGTERM を受信してもらいたいです。親が終了する前に、子が SIGTERM の処理を終了することは重要ではありません。
ただし、以下のコードではkill(0, SIGTERM)
、親から呼び出したときに子は SIGTERM を受け取りません。kill
manpageから、すべての子がこの SIGTERM を取得する必要があるようです。
親のシグナルハンドラーをセットアップしました。
フォークを必要とするシグナルを受け取った後、次のことを行います
ではdo_fork_stuff
、子供は 30 秒間眠ります。次に、保護者から電話kill(0, SIGTERM)
します。子は終了しません。
子供たちが SIGTERM を取得していない理由は何ですか?