pool - 在 python 中,执行 pool.map 时,是否可以每秒执行一次函数?

  显示原文与译文双语对照的内容

我在大型数据 array 上运行 pool.map,每分钟我都要打印报表。 有可能我理解,python 是同步语言,它不能像nodejs那样做。

也许它可以通过线程来完成。 或者如何?


finished = 0



def make_job():


 sleep(1)


 global finished


 finished += 1



# I want to call this function every minute


def display_status():


 print 'finished: ' + finished



def main():


 data = [...]


 pool = ThreadPool(45)


 results = pool.map(make_job, data)


 pool.close()


 pool.join()



时间: 原作者:

你可以使用永久线程计时器,如以下问题中所示: python threading.timer 重复功能每'n'第二次。


from threading import Timer,Event 



class perpetualTimer(object):



 # give it a cycle time (t) and a callback (hFunction) 


 def __init__(self,t,hFunction):


 self.t=t


 self.stop = Event()


 self.hFunction = hFunction


 self.thread = Timer(self.t,self.handle_function)



 def handle_function(self):


 self.hFunction()


 self.thread = Timer(self.t,self.handle_function)


 if not self.stop.is_set():


 self.thread.start()



 def start(self):


 self.stop.clear()


 self.thread.start()



 def cancel(self):


 self.stop.set()


 self.thread.cancel()



基本上这只是 Timer 对象的包装,在每次调用所需函数时创建一个新的Timer 对象。 从这个角度不要期望毫秒精度( 甚至关闭),但是对于你的目的,它应该是理想的。

使用这里示例将成为:


finished = 0



def make_job():


 sleep(1)


 global finished


 finished += 1



def display_status():


 print 'finished: ' + finished



def main():


 data = [...]


 pool = ThreadPool(45)



 # set up the monitor to make run the function every minute


 monitor = PerpetualTimer(60,display_status)


 monitor.start()


 results = pool.map(make_job, data)


 pool.close()


 pool.join()


 monitor.cancel()



编辑:

更清洁的解决方案可能是( 感谢以下评论):


from threading import Event,Thread 



class RepeatTimer(Thread):


 def __init__(self, t, callback, event):


 Thread.__init__(self)


 self.stop = event


 self.wait_time = t


 self.callback = callback


 self.daemon = True



 def run(self):


 while not self.stop.wait(self.wait_time):


 self.callback()



然后在代码中:


def main():


 data = [...]


 pool = ThreadPool(45)


 stop_flag = Event()


 RepeatTimer(60,display_status,stop_flag).start()


 results = pool.map(make_job, data)


 pool.close()


 pool.join()


 stop_flag.set()



原作者:

一种方法是使用主线程作为监视一个。 以下类似的内容应该适用:


def main():


 data = [...]


 results = []


 step = 0


 pool = ThreadPool(16)


 pool.map_async(make_job, data, callback=results.extend)


 pool.close()


 while True:


 if results:


 break


 step += 1


 sleep(1)


 if step % 60 == 0:


 print"status update" +.. .



我使用 .map() 代替 .map_async(),因为前者是同步的。 你可能还需要用更高效的方法替换 results.extend 。 最后,由于 GIL,速度改进可能比预期要小得多。

简而言之,你写的是一个有趣的问题:python 在问题的问题中是同步的。

原作者:
...