2017-06-26 10 views
0

周期的な間隔よりも実行に時間がかかることを定期的に行う方法をアドバイスしてください。 例えばpython:定期的なノンブロッキング検索を行う方法

def lookup(): 
    # do some lookups, retrieve info, let's assume it takes 60sec to complete 
    msg = {'abc':123} 
    time.sleep(60) 
    return msg 

class Publisher(object): 
    def __init__(self): 
     self._TIMEIT = 0 
     self._INTERVAL = 5 
     self._counter = 0 

    def xxx(): 
     t_start = time.time() 
     msg = lookup() 
     # do something with the value returned 
     save_msg_to_db(msg) 
     self._counter += 1 
     t_end = time.time() 
     self._TIMEIT = int(math.ceil(t_end - t_start)) 

    def run(): 
     while True: 
      # let's do the lookup every 5sec, but remember that lookup takes 60sec to complete 
      time.sleep(self._INTERVAL) 
      # the call to xxx() should be non-blocking 
      xxx() 

しかしrun方法は、定期的なタスク、 をスケジュールするための責任であり、それは反復処理としての機能xxxを呼び出すときに、それがブロックしてはいけません。

私はA Bad Coroutine Exampleで説明したように、xxx関数にすべての呼び出しでイベントループを作成するために考えていますが、どのようxxxノンブロッキングへの呼び出しを行うには?

PS。私はasyncio(以前はgeventを使用していた)にPython3.4を新しく使用していますが、ここではstupidと頼んでいるかどうかはわかりません。

したがってlookupは、完了までに60秒かかると思われる非同期ループを作成します。しかし、runメソッドでは、無限ループが実行されているので、5秒ごとにルックアップを実行したいと思っています。つまり、(1)どのくらい頻繁にルックアップ関数を呼び出しますか。(2)長いそれは(コードが簡潔にするために短縮)あなたのlookup()は主にI/Oを集約的であるので、あなたがスレッドとしてごxxx()方法を実行して、完全に罰金することができ

+0

は、あなたの 'のルックアップです() '関数はCPUを多用するか、I/O操作のために完了するのに時間がかかりますか? – zwer

+0

: "I/O操作のために完了するのに時間がかかります" – iamsterdam

+0

'lookup()が実行されている間はどうなりますか?あなたがバックグラウンドで(ノンブロッキングで)実行したい場合は、完了までに60秒かかり、5秒ごとに呼び出すとかなりすぐに、何千もの実行されます。つまり、あなたのチェック間隔(それ​​を拡張する)か 'lookup()'関数の呼び出し(前の呼び出しが完了しなかった場合に別の呼び出しをしないでください)があります。 – zwer

答えて

0

を完了するために、ルックアップを取ります

import threading 
import time 

class Publisher(object): 

    def __init__(self): 
     self._INTERVAL = 5 
     self._counter = 0 
     self._mutex = threading.Lock() 

    def xxx(self): 
     msg = lookup() 
     save_msg_to_db(msg) 
     with self._mutex: # make sure only one thread is modifying counter at a given time 
      self._counter += 1 

    def run(self): 
     while True: 
      time.sleep(self._INTERVAL) 
      t = threading.Thread(target=self.xxx) 
      t.setDaemon(True) # so we don't need to track/join threads 
      t.start() # start the thread, this is non-blocking 
+0

ありがとう@zwerは私にそれを評価させて、あなたに戻ってきます – iamsterdam

関連する問題