文章内容
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?
评论列表