2012-01-16 61 views
5

我試圖每秒運行三個函數(每個函數最多可能需要1秒鐘的時間)。然後,我想存儲每個函數的輸出,並將它們寫入單獨的文件。每秒運行多個函數,將結果寫入文件

目前我正在使用Timer s來進行延遲處理。 (我可以繼承Thread,但是這變得有點複雜了,這個簡單的腳本)

def main: 
    for i in range(3): 
     set_up_function(i) 
     t = Timer(1, run_function, [i]) 
     t.start() 
    time.sleep(100) # Without this, main thread exits 

def run_function(i): 
    t = Timer(1, run_function, [i]) 
    t.start() 
    print function_with_delay(i) 

什麼是處理來自function_with_delay輸出的最好方法?將結果追加到每個函數的全局列表中?

然後我可以把這樣的事情在我的主要函數的末尾:

... 
while True: 
    time.sleep(30) # or in a try/except with a loop of 1 second sleeps so I can interrupt 
    for i in range(3): 
     save_to_disk(data[i]) 

的思考?


編輯:新增我自己的答案作爲一種可能性

回答

7

我相信蟒蛇Queue模塊正是爲這種場景設計的。你可以做這樣的事情,例如:

def main(): 
    q = Queue.Queue() 
    for i in range(3): 
     t = threading.Timer(1, run_function, [q, i]) 
     t.start() 

    while True: 
     item = q.get() 
     save_to_disk(item) 
     q.task_done() 

def run_function(q, i): 
    t = threading.Timer(1, run_function, [q, i]) 
    t.start() 
    q.put(function_with_delay(i)) 
+1

+1這適用,因爲輸出是分開文件。如果它不平凡並且涉及輸出的組合,那麼在寫入之前,您將不得不等待所有排隊的項目完成。請務必在所獲取的項目上調用'task_done'。 – darvids0n 2012-01-16 04:08:01

+0

好主意!隊列是線程安全的,比list.append(data)好得多 – 2012-01-16 04:08:11

+0

我按照darvids0n的建議將調用添加到'task_done'。謝謝。 – srgerg 2012-01-16 04:18:09

1

我想說店名單列表(boolstr),其中bool是功能是否已經完成運行和str是輸出。每個函數使用一個互斥鎖來鎖定列表以追加輸出(或者如果您不關心線程安全性,則省略此項)。然後,有一個簡單的輪詢循環檢查所有的bool值是否爲True,如果是,則執行save_to_disk調用。

0

另一種方法是實現使用threading.Lock()類(從this answer拍攝)。這具有能夠在ItemStore上等待的優點,並且save_to_disk可以使用getAll,而不是輪詢隊列。 (對於大數據集更高效)

這特別適合於以設定的時間間隔(即每30秒)進行寫入,而不是每秒一次。

class ItemStore(object): 
    def __init__(self): 
     self.lock = threading.Lock() 
     self.items = [] 

    def add(self, item): 
     with self.lock: 
      self.items.append(item) 

    def getAll(self): 
     with self.lock: 
      items, self.items = self.items, [] 
     return items