オペレーティングシステムの概念を学ぶつもりです。以下は2つの簡単なPythonコードです。
while True:
pass
これ:
from time import sleep
while True:
sleep(0.00000001)
質問:なぜ最初のコードを実行するときはCPU使用量が100%ですが、2番目のコードを実行するときは1〜2%程度ですか?愚かに聞こえるかもしれませんが、なぜsleep
睡眠システムコールを使わずにユーザースペースモードのようなものを実装できないのですか?
注:私は睡眠を理解しようとしています。Linuxカーネルのシステムコールしかし、正直なところ、そこで何が起こっているのか理解できません。また、NOPアセンブリコードを検索した結果、実際には機能しないことがわかりました。何もないしかし、役に立たないこと(例:xchg eax、eax)を実行すると、CPU使用率が100%になるようです。しかし、よくわかりません。
ユーザー空間モードで実行できない省電力システムコールのアセンブリコードは何ですか? HLTに似ていますか?
また、次のようにコードでアセンブリを試しましたHLT
。
section .text
global _start
_start:
hlt
halter:
jmp _start
section .data
msg db 'Hello world',0xa
len equ $ - msg
ただし、このコードを実行すると、次のような一般的なカーネル保護エラーが表示されます。
[15499.991751] traps: hello[22512] general protection fault ip:401000 sp:7ffda4e83980 error:0 in hello[401000+1000]
たぶん何か関係があるかもしれませんが、保護リングそれとも私のコードが間違っていますか?ここで別の質問は、オペレーティングシステムがシステムコールで、HLT
または他の保護されたアセンブリコマンドを使用することですかsleep
?
ベストアンサー1
最初のコードを実行するときにCPU使用率が100%で、2番目のコードを実行したときに約1〜2%の理由は何ですか?
最初は「使用中のループ」なので、常にコードを実行しています。 2つ目は、オペレーティングシステムがこの特定のプロセスを一時停止(休止)することを望んでいることを示しているため、オペレーティングシステムはプロセスのスケジュールをキャンセルし、CPUを使用する他のプロセスがない場合、CPUはアイドル状態になります。
また、NOPアセンブリコードを検索した結果、実際には何もしないことがわかりました。
NOP =タスクなし:何の効果もないコードを積極的に実行しています。これを使用してコードを入力できますが、CPUを低電力状態に切り替えることはできません。
ユーザー空間モードで実行できない省電力システムコールのアセンブリコードは何ですか?
x86 CPUの最新のオペレーティングシステムは、mwait
他のCPUアーキテクチャは異なるコマンドを使用します。
ただし、このコードを実行すると、次のような一般的なカーネル保護エラーが表示されます。
これは、オペレーティングシステムが管理者モードでこれを行うようになっているためです。上記のように、オペレーティングシステムはプロセスのスケジュールを維持できる必要があるため、プロセス自体がCPUをアイドルモードにすることはできません。
ここでもう1つの問題は、オペレーティングシステムがスリープシステムコールでHLTまたは他の保護されたアセンブリコマンドを使用することです。
はい、そうです。スリープコール中は実行されませんが、スケジューラループ内でスケジューラが実行するプロセスがないことを検出すると実行されます。
パート1に関する質問です。いくつかの期間を使用している場合、つまり
sleep(0.0000000000000001)
スケジューラはまだ次のプロセスに進みますか?
実際のオペレーティングシステムの呼び出しについては、man 3 sleep
(秒単位の解像度)、man usleep
(マイクロ秒単位の解像度)、およびman nanosleep
(ナノ秒単位の解像度)を参照してください。
Pythonコードでどの浮動小数点を使用しても、Pythonが使用するシステムコールよりも優れた解像度を得ることはできません(変形が何であれ関係ありません)。
マンページには、「(少なくとも)usecマイクロ秒の間に呼び出しスレッドの実行を一時停止します」と記載されています。等なので、遅延がゼロであっても(そして直ちにスケジュールが変更されても)スケジュールがキャンセルされると仮定します。しかし、私はこれをテストしておらず、カーネルコードも読みませんでした。 。