1

私のプログラムは、ループごとに 1 回測定を行い、指定された時間 (この場合は 10 秒) スリープします。時間も計ります。2 つの方法で時間を測定します。1 回は time.strftime で、もう 1 回は time.clock() で。ほとんどのコンピューターで、これらの結果は完全に一貫しており、問題はありません。あるコンピューターでは、まったく同意しません。

問題のコード セグメントは次のとおりです。私のプログラムでは、3 つのスレッドで独立して実行されていました。self.delay は、ユーザー指定の遅延 (この場合は 10.0 秒) を保持する float です。

    cycles = 0
    startTime = time.clock()
    while(blah)
        cycleBeginTime = time.clock()
        ...

        t = time.strftime("%Y-%m-%d %H:%M:%S")

        ...

        cycles += 1
        cycleEndTime = time.clock()
        wakeUp = startTime + cycles * self.delay

        if cycleEndTime > wakeUp:  #we overslept
            continue
        else:
            #not guaranteed to sleep for the exact specified amount of time
            time.sleep(float(wakeUp - cycleEndTime))
        afterSleepTime = time.clock()
        print ("sleep(" + str(wakeUp - cycleEndTime) + ") lasted " +
               str(afterSleepTime - cycleEndTime) +" seconds\n" +
               "Total time for this cycle: " +
               str(afterSleepTime - cycleBeginTime) +
               "\ntime from start of cycle to sleep " +
               str(cycleEndTime-cycleBeginTime) )

time.clock で測定された時間のコンソール上の結果を次に示します。要約については、次の部分に進んでください。

sleep(9.8107975515) lasted 4.31354512806 seconds
Total time for this cycle: 4.50274184753
time from start of cycle to sleep 0.189196719463
sleep(9.83803382537) lasted 4.35964227608 seconds
Total time for this cycle: 4.5216022856
time from start of cycle to sleep 0.161960009523
sleep(9.83973893539) lasted 4.36409510551 seconds
Total time for this cycle: 4.52435043356
time from start of cycle to sleep 0.160255328054

sleep(15.3537603228) lasted 5.42625884166 seconds
Total time for this cycle: 5.56417636459
time from start of cycle to sleep 0.137917522931
sleep(15.3879203849) lasted 5.45131225502 seconds
Total time for this cycle: 5.5384287755
time from start of cycle to sleep 0.0871165204752
sleep(15.3801304296) lasted 5.45686671345 seconds
Total time for this cycle: 5.55443364994
time from start of cycle to sleep 0.0975669364944

sleep(19.7024141096) lasted 2.5903386547 seconds
Total time for this cycle: 2.81485116786
time from start of cycle to sleep 0.224512513157
sleep(19.7236584582) lasted 2.61606277881 seconds
Total time for this cycle: 2.81505236078
time from start of cycle to sleep 0.198989581976
sleep(19.7569903213) lasted 2.64424758408 seconds
Total time for this cycle: 2.8228942459
time from start of cycle to sleep 0.178646661821

sleep(26.8608515814) lasted 3.1923968974 seconds
Total time for this cycle: 3.44044448649
time from start of cycle to sleep 0.248047589093
sleep(26.9264651571) lasted 3.24803654453 seconds
Total time for this cycle: 3.42464766929
time from start of cycle to sleep 0.176611124756
sleep(26.9123819307) lasted 6.19344847627 seconds
Total time for this cycle: 6.39064386998
time from start of cycle to sleep 0.197195393715

sleep(30.50445713) lasted 11.3544706882 seconds
Total time for this cycle: 11.5452852063
time from start of cycle to sleep 0.190814518069
sleep(30.5479180492) lasted 11.4011029222 seconds
Total time for this cycle: 11.5583578442
time from start of cycle to sleep 0.157254922059
sleep(30.5384771841) lasted 11.3943939803 seconds
Total time for this cycle: 11.5739287254
time from start of cycle to sleep 0.179534745126

sleep(29.032023896) lasted 9.57638019147 seconds
Total time for this cycle: 9.6907935091
time from start of cycle to sleep 0.114413317628
sleep(28.9997437096) lasted 9.55454254173 seconds
Total time for this cycle: 9.70431450053
time from start of cycle to sleep 0.149771958799
sleep(29.0315669415) lasted 9.57838381284 seconds
Total time for this cycle: 9.69044695504
time from start of cycle to sleep 0.112063142198

sleep(29.2684610421) lasted 11.5343751591 seconds
Total time for this cycle: 11.7100907949
time from start of cycle to sleep 0.175715635808
sleep(29.4380200767) lasted 11.7063676658 seconds
Total time for this cycle: 11.7231073229
time from start of cycle to sleep 0.01673965716
sleep(29.2840066914) lasted 11.5395576362 seconds
Total time for this cycle: 11.7081641622
time from start of cycle to sleep 0.168606525989

time.strftime で取得したタイムスタンプの概要を、time.clock からの測定値と試行されたスリープ時間と比較して以下に示します。

2012-04-04 17:22:07
2012-04-04 17:22:17 (diff 10s. Attempted sleep time 10s   time.clock says 4.5s)
2012-04-04 17:22:32 (diff 15s. Attempted sleep time 15.4s time.clock says 5.4s)
2012-04-04 17:22:52 (diff 20s. Attempted sleep time 19.7s time.clock says 2.8s)
2012-04-04 17:23:46 (diff 54s. Attempted sleep time 27s   time.clock says 3.4s)
2012-04-04 17:24:16 (diff 30s. Attempted sleep time 30.5s time.clock says 11.5s)
2012-04-04 17:24:45 (diff 29s. Attempted sleep time 29s   time.clock says 9.7s)
2012-04-04 17:25:15 (diff 30s. Attempted sleep time 29.4s time.clock says 11.7s)

ご覧のとおり、time.strftime はスリープに最も一致しますが、常にではありません (2012-04-04 17:23:46 では一致しません)。一方、time.clock は常に完全に偽のナンセンスを提供します。これら 2 つの関数が完全にナンセンスな結果をもたらす原因となるものはありますか?

編集:簡潔にするために投稿を完全に書き直しました。

編集:まあ、解決策はありますが、理由がわかりません。 このページでは、time.clock() は、Windows で使用するとウォールクロック時間を提供しますが、Unix で使用すると CPU 時間を提供すると述べています。その後投稿を削除した回答者の 1 人が、time.clock() は CPU 時間であると誤って言いましたが、ドキュメントにもかかわらず、彼が正しいのではないかと思います。time.clock() へのすべての呼び出しを time.time() への呼び出しに置き換えたところ、問題のあるコンピューターでもプログラムが動作するようになりました。

4

2 に答える 2

0

動作がおかしい PC にはマルチコア CPU が搭載されていますか? 3.2 より前は、あるスレッドが 1 つのコアに設定され、GIL を解放し、別のコアに割り当てられた別のスレッドが GIL を取得する前に、最初のスレッドが GIL を再取得するという状況が発生する可能性がありました。詳細については、この投稿を参照してください。

アップデート:

もう少し調査するtime.clockと、 とtime.timeは必ずしも同じ時計を使用して時間を測定するとは限りません。あなたが発見したように、解決策はどちらかを選択し、それを使用することです。どれが最高の安定性を提供するかを確認するために、いくつかのテストを行う必要があります。

于 2012-04-05T01:28:08.593 に答える
0

アプリケーションのスリープ機能やタイマー機能が正しくないことを考えると、これにアプローチする最善の方法は、タイムスタンプと実行する目標時間を使用することです。

したがって、ターゲット時間を EPOCH + ExecuteTime に等しく設定し、間隔を小さい数に設定しますが、不要なサイクルを避けるために小さすぎないようにします。そして、実行時間をチェックするループの部分は、それをチェックする方法です。

アプリケーションが 1 ミリ秒でもハングすることを知っていますか? 開始された実際の時間に対してタイムアウトなどを確認するのではなく、中断したところから続行していると信じているだけです。

于 2012-04-05T00:00:47.580 に答える