2012-04-04 2 views
1

Моя программа измеряет один раз за цикл и спит для заданной величины, в этом случае 10 секунд. Он также измеряет время. Он измеряет время двумя способами. Один раз с time.strftime, а другой с time.clock(). На большинстве моих компьютеров эти результаты полностью согласованы, и у меня нет проблем. На одном компьютере они вообще не согласны.time.clock и time.strftime Дают абсолютно разные результаты

Вот этот сегмент кода. В моей программе он работал независимо в трех потоках. self.delay - это поплавок с заданной пользователем задержкой, в данном случае 10,0 секунд.

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 дает совершенно фиктивные нонсенс все время. Есть ли что-то, что приведет к тому, что эти две функции дадут полные бессмысленные результаты?

EDIT: полностью переписать сообщение для краткости.

EDIT: У меня есть решение, но я не понимаю, почему. This page говорит, что time.clock() дает время настенного времени, когда используется под Windows, но время CPU при использовании в Unix. Один из ответчиков, который с тех пор удалил свой пост, ошибочно сказал, что time.clock() - это процессорное время, но мне интересно, может ли он быть прав, несмотря на документы. Когда я заменил все свои вызовы на time.clock() с вызовами time.time(), моя программа теперь работает даже на проблемном компьютере.

+0

Как выглядит вывод на компьютере, где он работает? – agf

+0

На компьютере, где он работает, измерение time.clock составляет около 10 миллисекунд указанного времени сна, а также sleep, time.clock() и время.strftime все согласны друг с другом. – Strill

+0

Вы установили пакет CPython прямо с http://python.org или это какой-то дистрибутив, который может что-то делать с 'time.clock'? Какая версия Python? – agf

ответ

0

Наилучший способ приблизиться к этому, учитывая, что любые приложения спящего режима или функции таймера являются неправильными, заключается в использовании штампов времени и целевого времени для выполнения.

Итак, установите целевое время равным EPOCH + ExecuteTime, установите интервал на небольшое число, но не слишком малым, чтобы избежать ненужных циклов. И тогда ваша часть цикла, чтобы проверить время выполнения, как проверить это.

Вы знаете, когда приложение висит даже миллисекунду? Он не проверяет тайм-ауты и т. Д. Против фактического времени его начала, он просто полагает, что он продолжается, с того момента, когда он остановился.

+0

Это разумное решение, но мне бы хотелось хотя бы знать, что может быть причиной этого, поэтому я не получаю снова отбрасывается им. Это почти вызвало большую катастрофу в течение нескольких недель проекта. Я хочу сказать, что разница в несколько миллисекунд отлично подходит для моих целей, но выключение на 30 секунд слишком велико. – Strill

+0

Я думаю, что это ужасное решение. Это противоречит всему, чему научили люди в недавнем прошлом, хотя это может быть прагматичным обходным путем. – 0xC0000022L

+0

Это единственное решение для точных таймеров, функции таймера на любом языке являются неточными. Я написал игру, и нам нужно было разработать наши собственные функции таймера, чтобы быть точными, и именно так мы должны были сделать это на C++. В последнее время мне также пришлось разработать таймер для веб-сайта, который был точным, и мне также пришлось использовать этот метод для полной точности. Причина, по которой я сказал, иногда поток может зависать по разным причинам, и он не компенсирует, проверяя, что циклы процессора прогрессируют. –

0

Имеет ли неудобный ПК многоядерный процессор? До 3.2 можно было получить ситуацию, когда поток был установлен в одно ядро, выпустил бы GIL, и до того, как другой поток, назначенный другому ядру, мог бы получить GIL, первый поток снова приобрел его. См. this post для более подробной информации.

Update:

Немного больше исследований показывают, что time.clock и time.time не обязательно использовать те же часы для измерения времени. Как вы обнаружили, решение состоит в том, чтобы выбрать тот или другой, а затем просто использовать его. Вы захотите провести некоторое тестирование, чтобы убедиться, что обеспечивает лучшую стабильность.

+0

Нет, это не ядро. На самом деле те, на которых он отлично работает, оказались многоядерными. Также я переписал свой пост, чтобы попытаться сохранить его более кратким и включить некоторые новые данные, которые я проверил. – Strill