Ctrl-Zとkill -STOPの違いは何ですか?


14

makeシェルから(大規模なプロジェクトで)コマンドを実行すると、Ctrl-Zを入力してプロセスを停止し、シェルに戻ることができます。その後、fgプロセスを続行するために実行できます。

これを自動化するシェルスクリプトを作成しようとしています(具体的には、CPUの温度を数秒ごとに確認し、コンピューターが過熱しやすいため、高温になった場合はプロセスを停止します)。私の最初の試みは次のように機能しました(簡略化)。

make &
subpid="$!"

sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"

sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"

wait "$subpid"

残念ながら、これは機能しませんでした。プロセスにSIGSTOPを送信しても、プロセスは一時停止しませんでした(出力を端末に送信し続けることで明らかになりました)。make &コマンドラインで実行し、SIGSTOPを送信し、プロセスの状態をps;で確認しました。停止としてリストされていました(そしてSIGCONTを送信したときに再び開始しました)が、出力を吐き出し、コア温度を上昇させていました!Ctrl-Zで停止してもこの問題は発生しませんでしたが、スクリプトでそれを行う方法はわかりません。

Ctrl-Zとの違いは何kill -STOPですか?シェルスクリプトで前者の動作を取得するにはどうすればよいですか?


そして、はい、make再帰的に実行されています。実際、私はそれがいくつかのレベルに深くなると思います。
タイモン

回答:


12

Ctrl-Zとの違いは何kill -STOPですか?シェルスクリプトで前者の動作を取得するにはどうすればよいですか?

CTRL-Z通常、SIGTSTP(ブロック可能)を送信します。他のこととは別に、シェルはしばしばこれらの機会にttyを以前に保存された状態にリセットします。ただし、さらに重要なことは、制御端末プロセスグループがシェルのPIDに設定されていることです(そして再びで再開されたジョブのPIDに設定されますfg)。

元の問題に戻ります。たとえば、Cpufreqdのような温度依存の周波数スケーリングを使用することは、実際には爪にとってより良いハンマーかもしれません。


4

makeプロセスを停止する必要はありません。makeプロセスそのすべての子プロセスを停止します。makeは再帰的に実行されていたに違いありません。

試してみてset -m、の%1代わりに使用してください"$subpid"

set -mスクリプト内のデフォルトでオフになって「ジョブ制御」を、可能にします。一般的には悪い考えだと人々は考えているようですが、ユースケースではうまくいくと思います


4

セッションリーダーの負のPID値-PGIDを指定すると、プロセスグループ内のすべてのプロセスに信号を送信できます。

kill -STOP -"$subpid"

注:新しいセッションでプログラムを実行するには、を使用しますsetsid make。しかし、あなたの場合、それは必要ないと思います。ただし、makeが再帰的に実行される場合、makeの各インスタンスが独自のリーダーになる可能性があります(それについてはわかりません)。

別のオプションを使用することもできますkillall

killall -STOP make

Ctrl + Zとkill -STOPの違い:

  • Ctrl-Zは実際にTSTPを送信しますが、これはブロックできます。
  • STOPはブロックできません。

PGIDアプローチは機能せず、次の出力行を生成しました/usr/local/bin/myscript: line 38: kill: (-10202) - No such process。バックグラウンドプロセスは引き続き実行されました。私は考えていないkillallサブプロセスのいくつかはのように見えるので、アプローチはうまくいくshのではなくmake
タイモン

シグナルを送信するプロセスはすでに終了しているようです。shという名前のサブプロセスがmakeによって生成されます。makeおよび多くのサブプロセスの場合、おそらくすべての子のPIDを取得し、それらをすべて停止することが最善です。
ジュリジ

シェルスクリプトからではなく、シェルから手動で実行すると動作しました。これは、手動で実行した場合、ルートPID(他のユーザーがPGIDを継承した)は最初のmakeコマンドのものであったが、スクリプトから実行した場合、ルートPIDはシェルスクリプト自体からであったためだと考えています。
タイモン

1

Ctrl+ Cは、シグナルを使用してプロセスを強制終了するために使用されます。SIGINTつまり、丁寧な強制終了です。

Ctrl+ Z は、プロセスを一時停止するために使用されます。これは、シグナルSIGSTPを送信します。これはスリープ信号のようなもので、元に戻すことができ、プロセスを再開できます。

ただし、プロセスが中断されると、fg フォアグラウンドで再開)bg (バックグラウンドで再開)で再開できますが、強制終了されたプロセスを再開できません。これはCtrl+ CCtrl+の使用の違いZです。

中断されたプロセスを表示する方法は?

複数の中断されたコマンドがある場合、それらを一覧表示するには、jobsコマンドを使用します。出力は次のようになります。

[1]-  Stopped                 cat
[2]+  Stopped                 vi

バックグラウンドで一時停止中のプロセスを強制終了する方法は?

killコマンドを使用して:

kill %nここで、nはジョブ番号(ジョブ出力の角かっこ内の番号)であるため、catを強制終了しますkill %1

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.