17

ちょっと興味があるんだけど。関数 Sleep() は実際にどのように機能しますか (windows.h で宣言されています)。たぶんその実装だけでなく、誰でも。つまり、どのように実装されていますか? 特定の時間コードを「停止」させるにはどうすればよいですか? cin >> とそれらが実際にどのように機能するかについても興味があります。彼らは正確に何をしますか?

何かを実行し続けることを「ブロック」する方法を私が知っている唯一の方法は、while ループを使用することですが、stdin から読み取るメソッドを呼び出しているときに起こっていることと比較して、膨大な量の処理能力が必要であることを考慮してください (単純に比較してください)。しばらく (true) stdin からの読み取りまで)、それは彼らがしていることではないと思います。

4

7 に答える 7

29

OS は、スケジューラと呼ばれるメカニズムを使用して、管理しているすべてのスレッドまたはプロセスを一緒に適切に動作させます。

1 秒間に数回、コンピューターのハードウェア クロックが CPU に割り込み、OS のスケジューラーがアクティブになります。スケジューラは、実行しようとしているすべてのプロセスを調べて、次のタイム スライスで実行するプロセスを決定します。

決定に使用するさまざまなことは、各プロセスの状態と、それまでの経過時間によって異なります。そのため、現在のプロセスが CPU を大量に使用しており、他のプロセスの進行を妨げている場合、現在のプロセスを待機させ、別のプロセスでスワップして、何らかの作業を実行できるようにします。

ただし、多くの場合、ほとんどのプロセスは待機状態になります。たとえば、プロセスがコンソールからの入力を待機している場合、OS はプロセス情報を見て、待機している io ポートを確認できます。これらのポートをチェックして、プロセスが処理するデータがあるかどうかを確認できます。その場合、プロセスを再開できますが、データがない場合、そのプロセスは現在のタイムスライスでスキップされます。

に関してはsleep()、任意のプロセスが OS にしばらく待機することを通知できます。その後、スケジューラはハードウェア割り込みの前でもアクティブになり (これは、プロセスが読み取り可能なデータを持たないストリームからブロッキング読み取りを実行しようとしたときにも発生します)、OS はプロセスが何であるかを記録します。待っています。スリープの場合、プロセスはアラームが鳴るのを待っています。または、タイマーが切れるまでプロセスが再起動されるたびに、プロセスが中断することがあります。

OS は、何かによって実行中のプロセスがプリエンプトされた後にのみプロセスを再開するため、前述のプロセスの生成やハードウェア タイマーの割り込みなど、sleep()あまり正確ではありません。正確さの程度は OS またはハードウェアによって異なりますが、通常は次のようになります。 1 ミリ秒以上。

より高い精度が必要な場合、または非常に短い待ち時間が必要な場合、唯一のオプションは、言及したビジー ループ コンストラクトを使用することです。

于 2009-07-03T21:08:32.150 に答える
3

オペレーティング システムは、プロセスの実行方法をスケジュールします (どのプロセスがどの順序で実行されるかなど)。 おそらく、カーネルに「プロセッサをxミリ秒間Sleep()使用させないでください」と伝えるシステム コールを発行します。

于 2009-07-03T21:05:46.710 に答える
2

つまり、Sleep() は、プロセス/スレッドをしばらく無視するよう OS に指示します。

于 2009-07-03T21:15:37.753 に答える
1

「cin」は大量のオーバーロードされた演算子を使用します。通常は右ビット シフトである '>>' は、C++ のほとんどすべての種類の右側オペランドでオーバーロードされます。それぞれに個別の関数が提供され、コンソールから読み取り、入力を指定した変数タイプに変換します。例えば:

std::cin::operator>> (int &rhs);

それは本当の C++ ではありません — ストリームとオーバーロードをしばらく扱っていないので、戻り値の型や引数の正確な順序を覚えていません。それにもかかわらず、この関数は cin >> 整数変数を実行すると呼び出されます。

基礎となる正確な実装は、オペレーティング システムによって異なります。

于 2009-07-03T23:36:16.470 に答える
0

低レベルでは、システムには「スケジューラ」と呼ばれるルーチンがあり、実行中のすべてのプログラムからの命令を実際に実行する CPU にディスパッチします。"Sleep" や "usleep" などのシステム コールは、そのスレッドまたはプロセスを一定時間 IGNORE するようスケジューラに指示する命令に一致します。

C++ ストリームに関しては、"cin" はアクセスしている実際のファイル ハンドル (stdin と stdout は実際にはそのようなハンドルです) を隠し、それに対する ">>" 演算子は基になる読み取りと書き込みの呼び出しを隠します。インターフェースであるため、実装は OS 固有である可能性がありますが、概念的には、内部で printf や scanf などを実行しています。

于 2012-05-17T16:08:01.937 に答える
0

答えはオペレーティング システムによって異なりますが、一般的に言えば、オペレーティング システムは別のコードを別のスレッドの別の場所で実行するようにスケジュールするか、文字通り何もしない場合は、ハードウェア イベントが発生するまで CPU を待機させます。 CPU は割り込みハンドラと呼ばれるコードにジャンプし、実行するコードを決定できます。

于 2009-07-03T21:07:25.803 に答える
0

マルチスレッド プログラムでスレッド/プロセスをブロックするより制御された方法を探している場合は、セマフォ、ミューテックス、クリティカル セクション、およびイベントを参照してください。これらはすべて、プロセスまたはスレッドをブロックするために使用される手法です (while コンストラクトを介して CPU をロードすることはありません)。

それらは基本的に、ブロックされたスレッドが待機している待機/シグナルイディオムに基づいて機能し、別のプロセスがスレッドにシグナルを送り、再び開始するように指示します。これら (少なくとも Windows では) はタイムアウトを持つこともできるため、Sleep() と同様の機能を提供します。

于 2009-07-03T21:16:25.690 に答える