文章内容
2021/2/2 17:27:26,作 者: 黄兵
python Thread长时间运行问题
通过Linux服务长时间运行Python多线程程序,存在一些问题,在此做个总结:
下面以使用多线程运行的一段代码:
def ping_main(self): threads = [] for i in range(self._num_worker_threads): worker = Thread(target=self.ping, args=(self._queue,)) worker.daemon = True threads.append(worker) worker.start() ip_list = self.get_ip_list_by_csv() if ip_list: for ip in ip_list: self._queue.put(ip[1]) self._queue.join()
这里通过队列的方式在多线程中传递消息。
worker.daemon = True
,设置守护线程,当主线程退出之后,子线程也退出。
如果你查看当前活动线程,间隔一段时间活动线程数量不断增加,具体代码如下:
def ping_main(self): for i in range(self._num_worker_threads): worker = Thread(target=self.ping, args=(self._queue,)) worker.demon() worker.start() print(threading.active_count()) ip_list = self.get_ip_list_by_csv() if ip_list: for ip in ip_list: self._queue.put(ip[1]) self._queue.join()
threading.active_count()
每隔一段时间,数量都会增加,如果长时间运行程序,会提示:
error: can't start new thread
线程数量已经超过系统限制。
这里使用self._queue.join()
来阻塞队列,直到所有的队列数据处理完成。
但是即使增加thread.join()
还是会存在一些问题,具体代码如下:
def ping_main(self): for i in range(self._num_worker_threads): worker = Thread(target=self.ping, args=(self._queue,)) worker.setDaemon(True) worker.start() self._thread.append(worker) print(threading.active_count()) ip_list = self.get_ip_list_by_csv() if ip_list: for ip in ip_list: self._queue.put(ip[1]) self._queue.join() for item in self._thread: item.join() # stop workers,fix RuntimeError: can't start new thread # https://stackoverflow.com/questions/42401108/when-is-queue-join-necessary for i in range(self._num_worker_threads): self._queue.put(None) for t in self._thread: t.join() print(self._thread)
这里通过Linux服务依然会出现一些问题,现在没有查清楚具体问题处在哪里。
也就是说即使结束了Thread,长时间运行程序也存在各种各样的Bug无法查清。
经过研究可以使用Python 3.2新增的concurrent.futures,下载程序已经改写,等运行今天晚上一晚上,明天看看是否存在问题,如果不存在问题,将在下一篇文章具体分析concurrent.futures模块。
2021年2月3日早上更新:
经过一晚上运行,程序并没有大问题,各项功能正常,这篇文章详细分析了使用concurrent.futures的方式长时间运行程序的方法,欢迎围观。
参考资料:
3、When is Queue.join() necessary?
评论列表