【python】threadpool的内存占用问题

先说结论:

在使用多线程时,不要使用threadpool,应该使用threading, 尤其是数据量大的情况。因为threadpool会导致严重的内存占用问题!

 

对比threading和threadpool的内存占用

# coding=utf-8

import time
import os
import psutil
import json
import threadpool
import threading


class TEST(object):
    # 获取数据,使用yield, 每次返回一个len=10的list, list中的每一项是一个线程的数据
    def get_data(self):
        multi_list = list()
        for i in range(100):
            data = "abcdefg" * 100000
            multi_list.append(data)
            if len(multi_list) % 10 == 0:
                yield multi_list
                multi_list = list()

    # 测试函数
    def test(self):
        for data in self.get_data():
            mem = psutil.Process(os.getpid()).memory_info().rss
            print "[test] mem %s" % mem    # 打印内存占用情况
            self.deal_threadpool(data)      # 使用threadpool
            # self.deal_multi_thread(data)  # 使用threading

    # 待对比方法,threadpool
    def deal_threadpool(self, data_list):
        pool = threadpool.ThreadPool(10)
        requests = threadpool.makeRequests(self.sub_task, data_list)
        [pool.putRequest(req) for req in requests]
        pool.wait()

    # 待对比方法,threading
    def deal_multi_thread(self, data_list):
        threads = list()
        for data in data_list:
            threads.append(threading.Thread(target=self.sub_task, args=(data,)))
        for t in threads:
            t.start()
        for t in threads:
            t.join()

    def sub_task(self, data):
        return


if __name__ == "__main__":
    mem = psutil.Process(os.getpid()).memory_info().rss
    print "[main] mem %s" % mem
    obj = TEST()
    obj.test()
    mem = psutil.Process(os.getpid()).memory_info().rss
    print "[main] mem %s" % mem

 

结果:

1. 使用threadpool时

[main] mem 9760768
[test] mem 16764928
[test] mem 23924736
[test] mem 26820608
[test] mem 29720576
[test] mem 31911936
[test] mem 34795520
[test] mem 36978688
[test] mem 39161856
[test] mem 41340928
[test] mem 43524096
[main] mem 43606016

 

2. 使用threading时

[main] mem 9760768
[test] mem 16764928
[test] mem 23838720
[test] mem 16969728
[test] mem 23838720
[test] mem 16969728
[test] mem 23838720
[test] mem 16973824
[test] mem 23842816
[test] mem 16973824
[test] mem 23842816
[main] mem 16973824

 

对比可以看出,

使用threading时,每次线程退出可以正确的释放内存,内存占用的最大值很稳定。

使用threadpool时,每次线程退出后内存都没有释放,而是一直累加。在我实际使用的过程中,从mongo获取了大量的数据,threadpool在处理过程中占用的内存高达50g,而使用threading后内存占用稳定在了1g.

 

posted @ 2018-01-16 19:03  匡子语  阅读(4408)  评论(1编辑  收藏  举报