web-dev-qa-db-ja.com

効率的で高速Python sleep()を使用している間のWhileループ

Pyserialを使用してシリアルでデバイスと通信しようとしています。コマンドは継続的に送信される必要があるため、Pythonのwhileループに配置する必要があります。

私は現在このコードを使用しており、 pythonプロセスは100%CPUを使用します を確認しています:

while True:
    #do some serial sending here
    time.sleep(0.2)

このコードは機能します。ただし、送信速度は遅くなります。 sleep間隔を短くすることで高速化しようとしましたが、CPUに負荷がかかりすぎるようです。

つまり、CPUリソースの消費を抑えながら、whileループを効果的に反復する方法はありますか?

29
jhtong

遅いCPUの無駄な部分は、「シリアル送信を行う」ことです。短いスリープのwhileループは、ごくわずかなCPUを使用します。

シリアル送信コードを見せてください。それをスピードアップする方法があるかもしれません。

このかなり遅いCPUで私はこれを見ます:

import time
while True: time.sleep(0.2)      # 0% CPU
while True: time.sleep(0.02)     # 0% CPU
while True: time.sleep(0.002)    # 0.5% CPU
while True: time.sleep(0.0002)   # 6% CPU
while True: time.sleep(0.00002)  # 18% CPU

ループ内で追加の作業を行います。

import time
while True: range(10000) and None; time.sleep(0.2)      # 1% CPU
while True: range(10000) and None; time.sleep(0.02)     # 15% CPU
while True: range(10000) and None; time.sleep(0.002)    # 60% CPU
while True: range(10000) and None; time.sleep(0.0002)   # 86% CPU

インタープリターでそれらを実行し、ctrl-Cで各whileループを停止しました。

55
John La Rooy

ヨアヒムの答えに対するあなたのコメントに関して:

次に、マイクロコントローラーのコードを再設計する必要があります。それ以外の場合は、汎用コンピューターを、不要なコードを繰り返し反復する愚かな「マイクロコントローラー」、つまり100%CPUに変えるだけです。コンピューターを誤って使用する別の症状は、ハードウェアモーターの速度がシリアルインターフェイス経由でコマンドを送信する速度に依存するという事実です。高レベルのロジックをホストするコンピューターで「コマンド」する必要があります。また、マイクロコントローラーは、モーターの低レベルの反復制御を処理する必要があります。

6
Zoran Pavlovic

速度とCPU負荷の間のトレードオフを把握する必要があります。

メッセージ間でそれほど多くを行わずに短いデータバーストを送信する必要がある場合は、平均がまだ低い可能性があるため、CPU負荷が高い状態で短時間生き続けることができます。