2017-01-28 92 views
0

下面是我們希望能夠做到:的Python 3 sched.scheduler計時器開始

  1. 計劃多次呼籲,對於每毫秒的精確數量後,我們啓動一個定時器T.

  2. 設置別的東西最多在另一個線程S.

  3. 啓動線程的run並啓動定時器T.

我們該怎麼做?

這裏的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

謝謝!雖然這是封鎖。是否也被調度?我總是設法誤解Python文檔,而不是其他任何文檔。 –

+0

@ DouglasMyers-Turnbull你可以在兩種模式下['運行'](https://docs.python.org/3/library/sched.html#sched.scheduler.run),默認爲阻塞。 – niemmi

0

我只是想分享我們實際使用的解決方案。我繪製的X =預定時間和y =實際時間使用兩種方法執行散點圖:

  • 使用類似於niemmi的答案的東西,使用專用線程不睡覺輪詢使用time.sleep
  • # 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.0具有約1μs的平均絕對誤差(雖然某些預期偏壓)。我們完全犧牲了一個線程並使用了第二種方法。

我仍然發現sched包非常不直觀。