freeze – linux でプロセスを一時的に凍結できるか?

freeze linux process

気になったのですが、任意の処理を一定時間凍結する方法はないのでしょうか?

私が言いたいのは、あるアプリケーション(おそらくrootとして実行されている)が、既に実行されている別のプロセス(GUIとコマンドラインの両方のプロセス)の実行を一時停止して、後で再開することは可能でしょうか?言い換えれば、私は特定のプロセスを一定時間、linuxのスケジューラによってスケジュールされたくないのです

  55  Pal Szasz  2012-10-10


ベストアンサー

こちらをご覧ください

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

優雅な “ものはSIGTSTPで、その目的は、プロセスがその気になれば、SIGCONTを受け取るまで実行を中断してくださいと “親切に “お願いすることです。SIGTSTPの場合、プロセスはSIGTSTPを無視して実行を続けることができるので、SIGTSTPを扱うように設計されたプログラムの協力が必要です

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

ここで述べたものを含め、任意のシグナルを送信するには、kill, killall, pkill のようなプログラムを使うか、システムコール kill(2) を使うことができます。上記のいずれについても、プラットフォーム/アーキテクチャ/バージョンに依存する詳細や正誤表については、お使いのオペレーティングシステムのマニュアルを参照してください。これらのコマンドや syscall の中の “kill” という単語は間違った呼び方をしていることに注意してください。これらのコマンドはプロセスを終了させるためだけに設計されているわけではありません。シグナルのうちの特定のものを送信することでそれを行うことができますが、シグナルはプロセスの終了以外の機能にも使用できます。例えば、SIGSTOP はプロセスを一時停止するだけであり、このように送信できるシグナルはいくつかありますが、そのうちの一つに過ぎません

一定時間が経過した後に自動的にプロセスを再開する条件を追加するには、監視プロセスを起動させるためにタイマーを設定して実行中のままの監視プロセスを使用する必要があり、監視プロセスは再び kill(2) を呼び出して停止しているプロセスに SIGCONT シグナルを送り、カーネルに実行の再開を要求します。さらに、システムが非常に忙しい場合、監視プロセスはタイマーの期限が切れるまで起こされないかもしれないので、ウェイクアップが遅れるかもしれません

サスペンドされたプロセスのサスペンドと再開の非常に正確な精度に依存している場合、リアルタイム権限でモニタリングプログラムを実行する必要があるかもしれません (プロセスのリアルタイム化についての情報は この manpagesched_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がモニタープロセスを制御しているため、(sleepに渡された引数に基づいて)10秒間バックグラウンドで実行し続け、その後、(sleepに渡された引数に基づいて)起動して子プロセスを継続することに注意してください。しかし、これは制御スクリプトが終了してからずっと後になります。同期的に時間が経過するのを待ちたい場合は、screenの2回目の呼び出しを省略して、制御スクリプトにスリープとキルをハードコーディングすればいいだけです

実行することで、実際にプロセスがサスペンドされることをテストできます

screen -rS child

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

83  allquixotic  2012-10-10


はい、STOP信号を送ってプロセスを一時停止させ、CONTを送って続行させることができます

usage:

kill -STOP <pid>

kill -CONT <pid>

15  None  2014-01-15


もし、”freeze” の定義が適当に緩いのであれば、reniceコマンドをチェックしてみてください

Reniceでは、実行中のプロセスのスケジューリングの優先度を変更することができます

通常のプロセスのナイス値は 0 です。 ナイス値を上げると、”why don’t you go first” のように、プロセスをナイスにします。一方、ナイス値を下げると、プロセスはナイスではなくなります。ナイス値の範囲は-20~19です

誰でも自分のプロセスをより良くすることができます。ルートだけがプロセスをより良くしたり、他のユーザーのプロセスをより良く変更することができます

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

ここでは、私のローカルのlinuxボックスで実行した例を示します

ps -lを使用して、NI列を見てプロセスの良い値を確認してください

-> ps -l
F S   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 finish pts/0   vim
0 R 29190   794   402  0  76   0 - 15874 -      pts/0   ps

vimプロセスでrenice +10を実行すると、優先度が低くなります

-> renice +10 -p 1105
1105: old priority 0, new priority 10

-> ps -l
F S   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 finish pts/0  vim
0 R 29190  1998   402  0  78   0 - 15874 -      pts/0  ps

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

renice 20 -p &ltpid of interest>
sleep &ltcertain amount of time>
renice 0 -p &ltpid of interest>

(rootで実行することを忘れずに)


上記のps -l出力で、興味深い列が小さな青いボックスにきれいに表示されるように、少し自由にしたことに注意してください 🙂

12  Maurice  2012-10-13


タイトルとURLをコピーしました