Linuxプロセスの状態


89

Linuxでは、ディスクからブロックを読み取る必要がある場合、プロセスの状態はどうなりますか?ブロックされていますか?もしそうなら、実行する別のプロセスはどのように選択されますか?

回答:


86

ファイル記述子が返されるのを待っている間、read()またはwrite()そこから返される間、プロセスは「D」または「ディスクスリープ」と呼ばれる特別な種類のスリープ状態になります。このような状態にある間はプロセスを強制終了または中断できないため、これは特別です。ioctl()からの戻りを待機しているプロセスも、この方法でスリープ状態になります。

これの例外は、ファイル(端末やその他のキャラクターデバイスなど)がO_NONBLOCKモードで開かれるときであり、デバイス(モデムなど)が初期化するのに時間が必要であると想定されたときに渡されます。ただし、質問でブロックデバイスを指定しました。また、ioctl()非ブロックモードで開かれたfdでブロックされる可能性のあるものを試したことはありません(少なくとも故意ではありません)。

別のプロセスがどのように選択されるかは、使用しているスケジューラー、およびそのスケジューラー内で重みを変更するために他のプロセスが何を行ったかに完全に依存します。

特定の状況下での一部のユーザー空間プログラムは、再起動されるまで、この状態が永遠に続くことが知られています。これらは通常、他の「ゾンビ」と一緒にグループ化されますが、技術的に消滅していないため、この用語は正しくありません。


1
「ioctl()からの戻りを待機しているプロセスも、この方法でスリープ状態になります。」ブロッキングIOCTLを待機しているユーザースペースプロセスを強制終了したので、これは正しくありません。私が誤解していない限り
Hamzahfrq

このようテストの時間を計ることは非常に困難です。中断できないプロセスは強制終了できません。あなたがそれを殺すことができたなら、それは単にブロックしていました(カーネルはioctlのどの部分の真ん中にもありませんでした、そしてあなたが渡した場所のユーザースペースに対応する応答をコピーしました(または少なくともコピーの途中))。Linuxも、この記事が執筆された2009年以降、大きく変化しています。この現象はかつてのように観測できなくなっています。
Tim Post

133

プロセスがディスクからデータをフェッチする必要がある場合、操作の完了には長い時間がかかる可能性があるため、CPUでの実行を効果的に停止して他のプロセスを実行できます。ディスクのシーク時間は少なくとも5ミリ秒が一般的で、5ミリ秒は1000万ですCPUサイクル、プログラムの観点からの永遠性!

プログラマーの観点から(「ユーザー空間内」とも呼ばれます)、これはブロッキングシステムコールと呼ばれますwrite(2)(同じ名前のシステムコールの薄いlibcラッパーである)を呼び出した場合、プロセスはその境界で正確に停止しません。カーネルでは、システムコールコードを実行し続けます。ほとんどの場合、特定のディスクコントローラードライバー(ファイル名→ファイルシステム/ VFS→ブロックデバイス→デバイスドライバー)に至るまで、ディスク上のブロックをフェッチするコマンドは適切なハードウェアに送信されます。ほとんどの場合、高速操作。

次に、プロセスはスリープ状態になります(カーネル空間では、ブロッキングはスリープと呼ばれます-カーネルの観点からは「ブロック」されることはありません)。ハードウェアが最終的に適切なデータをフェッチすると、プロセスは実行可能としてマークされ、スケジュールされます。最終的に、スケジューラはプロセスを実行します。

最後に、ユーザー空間では、ブロッキングシステムコールが適切なステータスとデータを返し、プログラムフローが続行されます。

最もI / Oシステムコールを呼び出すことが可能である非ブロックモード(参照O_NONBLOCKopen(2)してfcntl(2))。この場合、システムコールはすぐに戻り、ディスク操作の送信のみを報告します。プログラマは、操作が正常に完了したかどうかを後で明示的にチェックし、その結果を(たとえばでselect(2))フェッチする必要があります。これは、非同期またはイベントベースのプログラミングと呼ばれます。

D状態TASK_UNINTERRUPTIBLELinux状態名で呼ばれる)に関するここでのほとんどの回答は正しくありません。Dの状態は、そのコードパスが場合のみ、カーネル空間コードパスにトリガされる特別なスリープモードで中断することができない(それはプログラムにあまりにも複雑になるので)、それは非常にするためにブロックすることを期待して、短時間。ほとんどの "D状態"は実際には見えないと思います。それらは非常に短命であり、「トップ」などのサンプリングツールでは観察できません。

いくつかの状況では、D状態で強制終了できないプロセスに遭遇する可能性があります。NFSはそのことで有名であり、何度も遭遇しました。常にローカルディスクに到達して高速エラー検出(SATAではエラータイムアウトは約100ミリ秒になる)を想定している一部のVFSコードパスと、実際にネットワークからデータをフェッチするNFSの間には、セマンティッククラッシュがあると思いますより回復力があり、回復に時間がかかります(300秒のTCPタイムアウトが一般的です)。Linux 2.6.25で導入された状態のクールなソリューションについては、この記事をお読みくださいTASK_KILLABLE。この時代の前に、カーネルスレッドにSIGKILLを送信することにより、NFSプロセスクライアントに実際に信号を送信できるハックがありましたが、rpciodその醜いトリックを忘れていました。…


2
詳細な回答については+1ですが、このスレッドでは2年近く回答が受け入れられています。最近の質問に手を貸したい場合は、「質問」リンクをクリックしてください。Stack Overflowへようこそ。貢献していただきありがとうございます。
GargantuChet 2011

20
この回答は、NFSについて言及する唯一の回答です。これは、一部の環境では、D状態のプロセスの最も一般的な説明です。+1。
Pinko

14
非常に良い答え、ありがとう。また、スワップアウトされたページを待機している間、プロセスはD状態になるため、スラッシングプロセスは長時間D状態になります。
cha0site

@zerodeux良い答えですが、スキーマ(ファイル名->ファイルシステム/ VFS->ブロックデバイス->デバイスドライバー)は(ファイル名-> VFS->ファイルシステム(ext3)->ブロックデバイス->デバイスドライバー)である必要があります
c4f4t0r

1
カーネルがスピンロックを待機するのに費やした時間(ディスクI / Oに関連する/proc/statかどうかに関係なく)はすべてD状態として報告されると想定しても安全でしょうか?
ウィック

8

I / Oを実行するプロセスはD状態(割り込み不可能なスリープ)に置かれ、CPUにプログラムの実行に戻るように指示するハードウェア割り込みがあるまで、CPUを解放します。man psその他のプロセス状態については、を参照してください。

カーネルによっては、実行可能なプロセスの実行キューを追跡するプロセススケジューラがあります。これは、スケジューリングアルゴリズムとともに、どのCPUにどのプロセスを割り当てるかをカーネルに伝えます。考慮すべきカーネルプロセスとユーザープロセスがあります。各プロセスにはタイムスライスが割り当てられます。タイムスライスは、使用が許可されているCPU時間のチャンクです。プロセスがすべてのタイムスライスを使用すると、スケジューリングアルゴリズムで期限切れとしてマークされ、優先順位が低くなります。

では2.6カーネル、そこにあるO(1)時間複雑スケジューラは、それほど関係なく、あなたが実行してアップ持っているか多くのプロセス、それは一定の時間内にCPUを割り当てません。ただし、2.6はプリエンプションを導入し、CPUロードバランシングは簡単なアルゴリズムではないため、さらに複雑です。いずれにせよ、それは効率的であり、I / Oを待機している間、CPUはアイドル状態のままになりません。


3

他の人がすでに説明したように、「D」状態(無停電スリープ)のプロセスは、psプロセスのハングの原因です。私には、RedHat 6.xと自動マウントされたNFSホームディレクトリで何度も発生しました。

D状態のプロセスをリストするには、次のコマンドを使用できます。

cd /proc
for i in [0-9]*;do echo -n "$i :";cat $i/status |grep ^State;done|grep D

プロセスの現在のディレクトリ、および問題のあるマウントされたNFSディスクを知るには、次の例のようなコマンドを使用します(31134をスリーププロセス番号に置き換えます)。

# ls -l /proc/31134/cwd
lrwxrwxrwx 1 pippo users 0 Aug  2 16:25 /proc/31134/cwd -> /auto/pippo

関連するマウントされたnfsファイルシステムに-f(強制)スイッチを指定してumountコマンドを実行すると、スリーププロセスをウェイクアップできることがわかりました。

umount -f /auto/pippo

ファイルシステムはビジーのためアンマウントされませんでしたが、関連するプロセスがウェイクアップし、再起動せずに問題を解決することができました。


1

プロセスがシングルスレッドであり、ブロックI / Oを使用しているとすると、プロセスはI / Oが完了するのを待ってブロックします。カーネルは、ナイス、優先度、前回の実行時間などに基づいて、その間に実行する別のプロセスを選択します。他に実行可能なプロセスがない場合、カーネルは何も実行しません。代わりに、マシンがアイドル状態であることをハードウェアに通知します(これにより、消費電力が低下します)。

I / Oの完了を待機しているプロセスは、通常、psやなどの状態Dで表示されtopます。


総メモリの約10%を使用していくつかのプロセスを起動しました。私はそれらの多くがD状態にあることに気づきました。これは、この特定のマシンのIOが遅いためですか?9つのプロセスがあるとすると、それらはIOをめぐって競合している可能性があり、それらの多くはD状態です。
Kemin Zhou

@KeminZhou CPU速度と比較すると、I / Oはかなり低速です。高速I / Oであってもです。単一のI / O負荷の高いプロセスは、SSDであっても、磁気ディスクでビジー状態になる可能性があります。10 I / O負荷の高いプロセスは、かなりの数をビジー状態にする可能性があります。
derobert 2017

1

はい、タスクはread()システムコールでブロックされます。準備ができている別のタスクが実行されます。他に準備ができているタスクがない場合は、アイドル状態のタスク(そのCPU用)が実行されます。

通常のディスク読み取りをブロックすると、タスクは「D」状態になります(他の人が指摘したとおり)。このようなタスクは、CPUを消費していなくても、平均負荷に貢献します。

他のいくつかのタイプのIO、特にttyとネットワークは、まったく同じように動作しません。プロセスは最終的に「S」状態になり、中断される可能性があり、平均負荷にカウントされません。



0

通常、プロセスはブロックされます。読み取り操作が非ブロッキングとしてマークされたファイル記述子に対して行われる場合、またはプロセスが非同期IOを使用している場合は、ブロックされません。また、ブロックされていない他のスレッドがプロセスにある場合、それらは実行を継続できます。

次に実行するプロセスに関する決定は、カーネル内のスケジューラー次第です。

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