简体   繁体   中英

time.clock and time.strftime Give Totally Different Results

My program takes a measurement once per loop and sleeps for a specified amount, in this case 10 seconds. It also measures time. It measures the time in two ways. Once with time.strftime, and another with time.clock(). On most of my computers, these results are totally consistent and I have no problems. On one computer, they don't agree at all.

Here's the code segment in question. In my program it was running independently in three threads. self.delay is a float holding the user-specified delay, in this case 10.0 seconds.

    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) )

Here's the results on the console for the time as measured with time.clock. Skip ahead to the next part for a summary.

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

Here's a summary of the timestamps taken with time.strftime, as compared with the measurements from time.clock and the attempted sleep time.

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)

As you can see, time.strftime agrees with sleep most, but not all of the time (they disagree on 2012-04-04 17:23:46), while time.clock gives completely bogus nonsense all the time. Is there something that would cause these two functions to give complete nonsense results?

EDIT: totally rewote post for brevity.

EDIT: Well, I have a solution, but I don't understand why. This page says that time.clock() gives wall-clock time when used under Windows, but CPU-time when used under Unix. One of the answerers who has since deleted his post, mistakenly said that time.clock() is CPU-time, but I wonder if he may be correct in spite of the docs. When I replaced all my calls to time.clock() with calls to time.time(), my program now works even on the problem computer.

The best way to approach this, considering any applications sleep or timer functions are incorrect, is to use time stamps and a target time to execute.

So, set the target time equals EPOCH + ExecuteTime, set the interval to a small number but not too small to avoid unrequired cycles. And then your part of the loop to check the execution time is how to check it.

You know when an application hangs for even a millisecond? It doesn't verify timeouts etc against the actual time it was initiated, it just believes it was continuing on from where it left off.

Does the misbehaving PC have a multi-core cpu? Prior to 3.2 it was possible to get a situation where a thread was set to one core, would release the GIL, and before another thread assigned to the other core could get the GIL the first thread had reacquired it. See this post for more details.

Update:

A little more research shows that time.clock and time.time do not necessarily use the same clock to measure time. As you have discovered, the solution is to pick one or the other, and then just use that one. You'll want to do some testing to see which provides the best stability.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM