2012-01-16 67 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