2017-01-28 6 views
0

가 여기에 우리가 할 수 있도록하려면 무엇 시작 : 우리는 타이머 (T)를 시작한 후파이썬 3 sched.scheduler 타이머는

  1. 일정 많은 전화 각을 밀리 초 정확한 번호를

  2. 타이머 (T)를 다른 스레드 S.

  3. 시작 스레드 S에서 실행하고 시작하는 최대 뭔가를 설정

어떻게 할 수 있습니까?

여기에 API reference이 있습니다. 실제로 scheduler.enter의 "시간 단위"가 scheduler.run에 대한 호출과 관련 될 것으로 예상했지만 에 대해서는scheduler.enter으로 호출하는 것 같습니다. 충분한 이벤트가 있으면 스케줄링 루프에서 i = 0으로 예약 된 작업과 i = 10 ** 6 사이에 시간 차이가 생깁니다. 스레드 S를 설정하는 시간 차이는 말할 나위없이 알려줍니다.

감사합니다.

답변

0

언제든지 heapq으로 자신의 스케줄러를 구현할 수 있습니다. 여기 start에 지연이 상대적 스케줄러의 간단한 예입니다 :

import heapq 
import time 

def fun(after, s): 
    print('{} after {} seconds: {}'.format(time.time(), after, s)) 

class Sched: 
    def __init__(self): 
     self.tasks = [] 

    def add_task(self, delay_seconds, priority, callback, args): 
     task = (delay_seconds, priority, callback, args) 
     heapq.heappush(self.tasks, task) 

    def start(self): 
     self.start_time = time.monotonic() 

     while self.tasks: 
      now = time.monotonic() 
      delta = now - self.start_time 
      nxt = self.tasks[0][0] 

      if delta < nxt: 
       time.sleep(nxt - delta) 
      else: 
       _, _, callback, args = heapq.heappop(self.tasks) 
       callback(*args) 

sched = Sched() 
sched.add_task(5, 1, fun, (5, 'second')) 
sched.add_task(5, 0, fun, (5, 'first')) 
sched.add_task(7, 0, fun, (7, 'third')) 

print(time.time(), 'start') 
sched.start() 
print(time.time(), 'end') 

출력 : 요청시 작업이 정확하게 실행되지 않습니다

1485623736.9788322 start 
1485623741.9809415 after 5 seconds: first 
1485623741.9809415 after 5 seconds: second 
1485623743.9846892 after 7 seconds: third 
1485623743.9846892 end 

참고. 이는 sleep의 제한 사항과 이전 작업을 실행하는 데 걸리는 시간 때문일 수 있습니다.

+0

감사합니다. 이것은 막고있다. 뿐만 아니라 sched입니까? 필자는 항상 파이썬 문서를 다른 어떤 것보다 오해 할 수밖에 없다. –

+0

@ DouglasMyers-Turnbull 두 모드 모두에서 [run()] (https://docs.python.org/3/library/sched.html#sched.scheduler.run) 할 수 있으며 기본값은 차단됩니다. – niemmi

0

우리가 실제로 사용한 솔루션을 공유하고 싶었습니다. 수면없이 폴링 전용 스레드를 사용하여 time.sleep

  • 를 사용하여, niemmi의 대답과 유사한 것을 사용

    • : 나는 X = 예약 된 시간과 두 가지 방법을 사용하여 실행에 대한 Y = 실제 - 시간의 분산 플롯을 그래프로 :

      # where queue is a DeQueue that pops the earliest scheduled time first 
      r = range(0, len(self._stimulus_list)) 
      t0 = monotonic() 
      for _ in r: 
          nxt = queue.get_nowait() 
          while monotonic() - t0 < t_now: pass 
          nxt.execute() 
      

    번째 방법 가까워 1μs의 약 1.0의 평균 절대치 오차 (일부 예상 바이어스 비록) 슬로프를 가졌다. 우리는 실을 완전히 희생하고 두 번째 방법을 사용했습니다.

    sched 패키지는 여전히 반 직관적입니다.