web-dev-qa-db-ja.com

Linuxでプロセスを一時的にフリーズできますか?

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

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

53
Pal Szasz

こちら を参照

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

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

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

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

一定の時間が経過した後にプロセスを自動的に再開する条件を追加するには、実行中のままの監視プロセスを使用し、タイマーを設定して監視プロセスをウェイクアップし、次にkill(2)を再度実行し、カーネルに実行の再開を要求するために、停止したプロセスにSIGCONTシグナルを送信します。 Linuxには、さまざまな精度と精度のタイミングメカニズムがいくつかあります。さらに、システムが非常にビジーな場合は、タイマーが期限切れになるまで監視プロセスが起動しない場合があり、ウェイクアップが遅延する可能性があります。

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

これを実装するためにどのテクノロジーを使用するかを示していませんでした。最低限、少なくとも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秒間実行され続けることに注意してください)その後、起動して子プロセスを続行します。しかし、これは制御スクリプトが終了してからかなり後になるでしょう。時間の経過を同期的に待機したい場合は、screenへの2番目の呼び出しを省略し、スリープとハードコーディングを制御スクリプトにハードコーディングします。

実行することでプロセスが実際に一時停止することをテストできます

screen -rS child

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

81
allquixotic

はい、それを行うには、プロセスに[〜#〜] stop [〜#〜]シグナルを送信してプロセスを一時停止し、次に[〜#〜] cont [〜# 〜]続行します。

使用法:

kill -STOP <pid>

kill -CONT <pid>
15
user8228

「フリーズ」の適切に緩い定義がある場合は、reniceコマンドを確認してください。

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

通常のプロセスのNice値は0です。Nice値を大きくすると、「最初に行ってみませんか」のように、プロセスがより美しくなります。ニースの値を小さくすると、「邪魔にならない、急いでいる」のように、プロセスのニースが少なくなります。ニース値の範囲は-20〜19です。

誰でも自分のプロセスをより良くすることができます。 rootだけがプロセスのniceを少なくしたり、別のユーザーのプロセスをniceに変更したりできます。

プロセスのNice値を19に設定すると、システムの他のものが必要としない場合にのみ実行されます。

これは私のローカルLinuxボックスで実行した例です。

使用する ps -lとNI列を見て、プロセスのNice値を確認します。

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

ランニング renice +10 vimプロセスでそれを実行すると、低い優先度で実行されます。

-> 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仕上げpts/0 vim 
 0 R 29190 1998 402 0 78 0-15874-pts/0 ps 
 

「フリーズ」を引き延ばして「システム上の他の人に迷惑をかけない」ことを意味すると仮定すると、次のようにスクリプト化できます。

 renice 20 -p&lt <興味のあるpid >> 
 sleep&lt一定の時間> 
 renice 0 -p&lt&興味のあるpid> 

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


私は上記のものといくつかの自由を取ったことに注意してくださいps -l出力は、興味深い列を取得し、小さな青いボックスにうまく表示されます:)

11
Maurice