2014-06-16 3 views
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)) 

(실제로는 읽기 쉽게 여기를 단축 X 시간을, 실행 루프에서의)이 105 회를 실행 한 후, 나는 실행 시간에 몇 가지 이상한 변화를 참조하십시오. 여기에 작은 샘플

      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 

슬립 간격이 항상 동일하게 보이지만, 정지 시간이 매우 다르며, 종료 시간뿐만 아니라 왜 내가 궁금에게 있습니다. 항목이 대기열에 놓인 직후에 프로세스가 종료되지만 잠시 시간이 걸릴 것 같습니다.

여기 무슨 일 이니?

EDIT : 적절한 위치에 process.start()를 추가했습니다.

+0

while 루프 대신에'process.join()'을 사용하면 시간이 어떻게됩니까? – daveydave400

+0

또한, 종료 및 종료 시간은 스레드를 생성하는 시간을 포함하는'start_time'을 사용합니다. 쓰레드가 생성 된 후에'start_time'을 설정하면 시간이 좀 더 안정적으로 보일 수도 있습니다. 그리고 언제 당신은'process.start()'를 호출합니까? – daveydave400

+0

생산 과정에서 process.join()을 시도하지 않았습니다. 여러 프로세스가 시작되었습니다. 이제 막 다른 종료 시간이있었습니다. (다른 것들도 가능하지만, 초당 수는 아니고 누적 결과 만 출력합니다.) – polkid

답변

1

이것은 만족스런 대답은 아니지만 표시된 코드가 다른 지연을 유발할 수있는 것처럼 보이지 않기 때문에 운영 체제 일정을 기반으로 한 것 같습니다. 여기에 몇 가지 중요한 요소가 있습니다. 당신은 동시에 때문에 GIL의 실행되지 않습니다 파이썬에서 스레드를 사용하는

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

: 당신은 그 자체가 따라 작거나 더 많은 시간이 걸릴 수 있습니다 말한다 sleep 기능을 사용하고 있습니다. 그리고 마침내이 테스트를 실행하는 컴퓨터가 실행하는 동안 무엇을 했습니까? 어쩌면 파이썬 프로세스가 예정대로 자주 스케줄되지 않을 수도 있습니다. 그 간격이 스레드 생성 시간이 꽤 일정하다는 것을 보여주기 전에 나의 코멘트는 약간 잘못되었습니다. 관련된 모든 코드를 표시하지 않으면 다른 요소 (예 : IO 대기를 유발하는 파일 읽기/쓰기)가있을 수 있습니다.

어쩌면 빠른 전성 검사하십시오 :

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

편집

그리고 당신은 다음 join를 사용하는 메인 쓰레드가 기다리고 차단 될 경우, 내 댓글에서 다시 join를 불러옵니다을 스레드와 실제 코드를 실행하지 않습니다. 이 방법을 사용하면 정지 신호를 잡기 위해 스레드에 처리 시간을 줄 수 있습니다.

+0

답변 해 주셔서 감사합니다! 폴링 루프에 time.sleep (0.001)을 추가하는 것이 어떤 이유로 타이밍을 강화하는 데 실제로 도움이되었다고 생각합니다. 나는 그 시간에 수집 된 데이터 포인트의 수가 바뀌는 지 확인하기 위해 몇 가지 테스트를해야 할 것이다. – polkid