9

リストから繰り返しメッセージをすばやく正確に送信する必要があります。1 つのリストは、+/- 10ms のウィンドウで 100ms ごとにメッセージを送信する必要があります。以下のコードを使用してみましたが、問題は、タイマーが 100 ミリ秒待機し、その後すべての計算を実行する必要があり、タイマーが許容範囲外になることです。

単純に待ち時間を減らすのは面倒で、信頼性の低いハックです。ループ中にリストが編集された場合に備えて、メッセージ ループの周りにロックがあります。

100ms前後で一貫してメッセージを送信するようにPythonを取得する方法について考えていますか? ありがとう

from threading import Timer
from threading import Lock

class RepeatingTimer(object):
    def __init__(self,interval, function, *args, **kwargs):
        super(RepeatingTimer, self).__init__()
        self.args = args
        self.kwargs = kwargs
        self.function = function
        self.interval = interval
        self.start()

    def start(self):
        self.callback()

    def stop(self):
        self.interval = False

    def callback(self):
        if self.interval:
            self.function(*self.args, **self.kwargs)
            Timer(self.interval, self.callback, ).start()

def loop(messageList):
    listLock.acquire()
    for m in messageList:
        writeFunction(m)
    listLock.release()


MESSAGE_LIST = [] #Imagine this is populated with the messages
listLock = Lock()
rt = RepeatingTimer(0.1,loop,MESSAGE_LIST)
#Do other stuff after this

writeFunction によって多少の遅延が発生することは理解していますが、許可されているのは 10 ミリ秒以内です。基本的に、メッセージごとに 100 ミリ秒ごとに関数を呼び出す必要があります。メッセージリストは小さく、通常は要素よりも少ないです。

次の課題は、これを 10ms、+/-1ms ごとに動作させることです:P

4

3 に答える 3

11

はい、単純な待機は面倒であり、より良い代替手段があります.

まず、Python で高精度のタイマーが必要です。いくつかの代替手段があり、OS によっては、最も正確なものを選択することをお勧めします。

次に、基本的なプリエンプティブ マルチタスクを認識し、高精度のsleep機能はなく、実際の解像度も OS ごとに異なることを理解する必要があります。たとえば、Windows について話している場合、最小のスリープ間隔は約 10 ~ 13 ミリ秒になる可能性があります

そして 3 番目に、非常に正確な時間間隔で待機することは常に可能であることを覚えておいてください (高精度のタイマーがあると仮定します) が、CPU 負荷が高いというトレードオフがあります。この手法はビジー待機と呼ばれます。

while(True):
    if time.clock() == something:
         break

したがって、実際の解決策は、ハイブリッド タイマーを作成することです。通常のsleep関数を使用して間隔の主要部分を待機し、ループ内で高精度タイマーのプローブを開始し、sleep(0)トリックを実行します。Sleep(0)(プラットフォームに応じて) 可能な限り最小限の時間を待機し、残りのタイム スライスの残りを他のプロセスに解放し、CPU コンテキストを切り替えます。ここに関連する議論があります。

このアイデアは、Ryan Geiss のTiming in Win32の記事で詳しく説明されています。これは C 言語であり、Windows API 用ですが、基本原則はここでも適用されます。

于 2013-03-23T13:30:18.140 に答える
0

これを試して:

#!/usr/bin/python
import time;  # This is required to include time module.
from threading import Timer

def hello(start, interval, count):
    ticks = time.time()
    t = Timer(interval - (ticks-start-count*interval), hello, [start, interval, count+1])
    t.start()
    print "Number of ticks since 12:00am, January 1, 1970:", ticks, " #", count 

dt = 1.25 # interval in sec
t = Timer(dt, hello, [round(time.time()), dt, 0]) # start over at full second, round only for testing here
t.start()
于 2013-05-24T01:06:06.287 に答える
0

開始時刻を格納します。メッセージを送信します。終了時刻を取得します。timeTaken=end-start を計算します。FP 秒に変換します。スリープ(0.1回)。ループバックします。

于 2013-03-23T09:44:55.043 に答える