文章内容

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的方式长时间运行程序的方法,欢迎围观。


参考资料:

1、queue --- 一个同步的队列类

2、threading --- 基于线程的并行

3、When is Queue.join() necessary?

4、python and ipython threading.activeCount()

5、error: can't start new thread

分享到:

发表评论

评论列表