0

データを収集するためにスクリプトを実行していますが、タイミングに奇妙な違いがあることに気付きました。

FTDI ライブラリを介して I2C からデータをポーリングするスクリプトがあり、3.5 HZ でデータを取り込みます。それはしっかりしていて、うまく機能します。ここにあります(と呼びましょうpoll_data.py):

while time.time() < start_time + duration_in_seconds:
    if not stop_queue.empty():
        if stop_queue.get():
            logger.debug('Break received, exiting collection after {0} seconds'.format(time.time() - start_time))
            break
    data = get_data()
    cache.append(",".join(str(x) for x in [time.time() - start_time] + data]))
    counter += 1
    if len(cache) == 50:
        write_to_log_file(file_id, cache)
        cache = []

キューが追加されたため、このスクリプトを非同期で実行し、外部のタイミングで停止できます。

いくつかのテストを実行した後、奇妙な停止時間が発生することに気付きました。簡単なテストがあるとします。

import time
from threading import Thread
from poll_data import polling, stop_queue

start_time = time.time()
test_time = 60
duration = 80
process = Thread(target=polling, args=duration)
process.start()
interval = test_time - (time.time() - start_time)
time.sleep(interval)
stop = time.time()
stop_queue.put(True)
while process.is_alive():
    pass
end = time.time()
run_information.append((start_time, interval, stop - start_time, end - start_time))

これを 105 回実行した後 (実際には x 回実行されるループ内にあり、読みやすくするためにここでは短縮されています)、実行時間に奇妙な変動が見られます。ここに小さなサンプルがあります

                         Run information                             
     Start      |    Interval     |   Process End   |    Finished      
1402934605.5525 |         59.9994 |         61.5621 |         64.3632  
1402934670.9171 |         59.9991 |         60.5022 |         62.8066  
1402934734.7252 |         59.9995 |         71.3656 |         77.0946  
1402934812.8211 |         59.9996 |         61.4797 |         61.6411  
1402934875.4637 |         59.9995 |         60.7879 |         60.7954  
1402934937.2605 |         59.9995 |         60.2218 |         60.5099  
1402934998.7719 |         59.9995 |         62.2200 |         65.0900  
1402935064.8633 |         59.9994 |         60.0802 |         60.4974  
1402935126.3622 |         59.9994 |         61.5364 |         63.3869  
1402935190.7505 |         59.9995 |         61.5147 |         61.9220  



Average Interval 59.99951714    Max 59.9998     Min 59.9991
                 62.28667048        71.3757         60.0485
                 64.23963714        77.0946         60.2074

睡眠間隔は常に同じに見えるのに、停止時間は大きく異なり、終了時間も同じである理由が気になります。アイテムがキューに入れられた直後にプロセスが終了しますが、それには時間がかかりますか?

何が起きてる?

編集: 適切な場所に process.start() を追加しました。

4

1 に答える 1

1

これは満足のいく答えではないかもしれませんが、あなたが示したコードは他の遅延を引き起こす可能性があるようには見えないので、オペレーティング システムのスケジューリングに基づいているだけだと思います。ここで重要な要素がいくつかあります。次の関数を使用していますが、次のsleepように時間がかかる場合があります。

https://docs.python.org/2/library/time.html#time.sleep

GIL のために Python で同時に実行されないスレッドを使用しています。最後に、これらのテストを実行している間、これらのテストを実行しているコンピューターは何をしていたのでしょうか? おそらく、Python プロセスが必要な頻度でスケジュールされていなかったのでしょう。スレッドの作成時間はかなり一定であることを間隔が示しているため、前の私のコメントは少し間違っていました。関連するすべてのコードが表示されていない場合は、他の要因が考えられます (たとえば、IO 待機の原因となるファイルの読み取り/書き込み)。

簡単なサニティチェックを試してみてください:

import time
start = time.time()
time.sleep(60)
stop = time.time()
print stop - start

編集

joinそして、私のコメントからもう一度取り上げます。使用するjoinと、メインスレッドはスレッドの待機中にブロックされ、実際のコードは実行されません。このようにして、停止シグナルをキャッチするためにスレッドに任意の処理時間を与えることができます。

于 2014-06-16T20:10:41.170 に答える