Linuxでプロセスを一時的に凍結できますか?


53

特定の時間プロセスをフリーズする方法があるかどうか疑問に思っていましたか?

つまり、あるアプリケーション(おそらくルートとして実行)が、すでに実行中の別のプロセス(GUIとコマンドラインの両方のプロセス)の実行を一時停止して、後で再開することは可能ですか?言い換えれば、特定のプロセスが特定の時間、Linuxスケジューラーによってスケジュールされることは望ましくありません。

回答:


81

こちらをご覧ください

プロセスの実行を一時停止できるシグナルは2つあります。1つは「優雅」で、もう1つは「強制」です。

「優雅な」ものはSIGTSTPであり、その目的は、プロセスに「いい感じ」であると感じたら、を受け取るまで実行を一時停止してくださいSIGCONT。の場合SIGTSTP、プロセスはSIGTSTPを無視して、とにかく実行を継続できるため、SIGTSTPを処理するように設計されたプログラムからの協力が必要です。

「強力な」ものはSIGSTOPであり、その目的は、そのプロセスに関連するすべてのユーザー空間スレッドを中断することです。プロセスが無視するのと同じくらいプロセスが無視SIGSTOPすることは不可能ですSIGKILL(後者はプロセスを強制的に強制終了します)。

次のようなプログラムを使用することができ、ここで言及したもののいずれかを含む、任意の信号を送信するにはkillkillallまたはをpkill。またはシステムコールを使用しますkill(2)。プラットフォーム/アーキテクチャ/バージョン依存の詳細および上記のエラータについては、オペレーティングシステムのマンページを参照してください。これらすべてのコマンドとシステムコールの「kill」という言葉は、間違った呼び名であることに注意してください。これらのコマンドは、プロセスを終了するためだけに設計されたものではありません。彼らはできる信号の特定のものを送信することによって、それを行います。しかし、シグナルはプロセスの終了以外の機能にも使用できます。たとえばSIGSTOP、プロセスを一時停止するだけであり、この方法で送信できるいくつかのシグナルの1つにすぎません。

自動的に一定の期間が経過した後にそのプロセスを再開の条件を追加するには、遺体が動作していることのプロセスを監視するいくつかの並べ替えを使用する必要があり、その後、順番に呼び出し、監視プロセス、ウェイクアップするためにタイマーをセットしますkill(2)もう一度とをSIGCONTカーネルに実行を再開するよう要求するために、停止したプロセスにシグナルを送信します。Linuxには、さまざまな精度と精度のタイミングメカニズムがいくつかあることに注意してください。さらに、システムが非常にビジーの場合、タイマーが時間切れになるまで監視プロセスが起こされないため、ウェイクアップが遅れる場合があります。

中断および中断されたプロセスの再開の非常に正確な精度に依存している場合は、リアルタイムの許可で監視プログラムを実行する必要があります(プロセスをリアルタイムにする方法については、このマンページを参照sched_setscheduler(2)てください)。また、Linuxカーネルの機能である高解像度タイマー(ハードウェアがそれらをサポートしている場合にのみ使用可能)をリアルタイムスケジューリングと組み合わせて使用​​して、非常に正確で、ミリ秒未満のタイミング精度を得ることができます。ウェイクアップし、信号を送信して、監視対象プロセスを非常に迅速に再開します。

これを実装するために使用するテクノロジーを指定しませんでした。少なくともbashスクリプトが必要になりますが、そのように非常にきめ細かいタイミングを取得することはできません。これは、クエリの概念を証明するだけのbashの「スクリプト」です(テストされていないので注意してください)。正確なタイミングが必要な場合は、おそらくC / C ++または別のネイティブ言語でプログラムを作成し、リアルタイムスケジューリングとhrtimersを使用する必要があります。

#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"

スクリプトは終了し、制御スクリプトは終了しますがscreen、モニタープロセスの制御により、(渡された引数に基づいて)10秒間バックグラウンドで実行を続けsleep、その後、起動して子プロセスを続行します。しかし、これは制御スクリプトが終了してからずっと後になります。時間が経過するまで同期的に待機する場合は、2番目の呼び出しを省略しscreen、スリープをハードコードして、制御スクリプトに強制終了します。

実行することにより、プロセスが実際に中断することをテストできます。

screen -rS child

このスクリプトを開始した後。コンソールには何も表示されません。次に、タイマーが切れると(10秒)、base64データ(0〜9およびAFのランダムな文字)が画面にあふれます。Ctrl + Cを押して終了します。


PoC bashスニペットを含む非常に良い非常に完全な回答。いいね!
fgysin

TCP接続のようなネットワークセッションの途中でプロセスがフリーズした場合、続行すると、そのネットワークセッションが破損したり、ドロップしたりしますか?これに定義された動作はありますか?
CMCDragonkai

@cmcdragonkaiは、停止中のプロセスが実行されていないため、fdからの読み取りまたは書き込みができないため、TCPセッションでバッファーがいっぱいになるまでカーネルがバイトを転送し続けるためです。プロセスを凍結することは、異なるチェックですhttps://www.kernel.org/doc/Documentation/power/freezing-of-tasks.txt
ニザムモハメド

プロセスをフォアグラウンドに戻した後もTCP接続を継続できることがわかりました(タイムアウトはアプリケーション固有で、TCPキープアライブがありますが、アプリケーションレベルのキープアライブもあります)。凍結プロセスは、コンピューターが休止状態またはスリープモードにあることを意味するようです。そうですか?
CMCDragonkai

このスクリプトは、非協力的なコードには影響しません。gist.github.com
ceremcem

14

はい、プロセスにSTOPシグナルを送信してプロセスを中断し、CONTを送信して続行することにより、これを行うことができます。

使用法:

kill -STOP <pid>

kill -CONT <pid>

11

「フリーズ」の定義が適切に緩い場合は、reniceコマンドをチェックアウトできます。

Reniceでは、実行中のプロセスのスケジューリング優先順位を変更できます。

通常のプロセスnice値は0です。nice値を増やすと、「最初に行かない理由」のように、プロセスがより良くなります。nice値を小さくすると、「邪魔にならないで、急いでいます」のように、プロセスの質が低下します。nice値の範囲は-20〜19です。

誰でも自分のプロセスをより良くすることができます。rootのみが、プロセスの見栄えを悪くしたり、別のユーザープロセスの見栄えを変更したりできます。

プロセスのnice値を19に設定すると、システム上で他に何もしたくない場合にのみ実行されます。

ローカルLinuxボックスで実行する例を次に示します。

ps -lNIの列を使用して見て、プロセスの素晴らしい値を確認してください。

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 75 0-16547 wait pts / 0 bash
0 T 29190 1105 402 0 75 0-23980終了ポイント/ 0 vim
0 R 29190 794 402 0 76 0-15874-pts / 0 ps

実行中のrenice +10Vimのプロセスには、それが低い優先度で実行するようになります。

-> renice +10 -p 1105
1105:古い優先度0、新しい優先度10

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 76 0-16547 wait pts / 0 bash
0 T 29190 1105 402 0 95 10-23980仕上げ点/ 0 vim
0 R 29190 1998 402 0 78 0-15874-pts / 0 ps

「フリーズ」を「システム上の他の人に迷惑をかけない」ように拡張できると仮定すると、次のようなスクリプトを作成できます。

renice 20 -p <対象のpid>
睡眠<一定の時間>
renice 0 -p <対象のpid>

(ルートとして実行することを忘れないでください)。


上記のps -l出力を少し自由にして、小さな青いボックスに興味深い列がうまく表示されるようにしてください:)

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