Python多处理逐渐增加内存,直到它运行我们的

Python多处理逐渐增加内存,直到它运行我们的,python,multithreading,memory,memory-leaks,multiprocessing,Python,Multithreading,Memory,Memory Leaks,Multiprocessing,我有一个包含多个模块的python程序。它们是这样的: 作业类,它是入口点并管理程序的整个流程 任务类,它是要在给定数据上运行的任务的基类。许多专门为不同数据列上的不同计算类型创建的子任务类都是从任务类派生的。假设数据中有10列,每列都有自己的任务进行处理。例如,CurrencyConverterTask可以使用“price”列返回本地货币值等 许多其他模块,如获取数据的连接器、utils模块等,我认为与这个问题无关 程序的一般流程是:从数据库连续获取数据->处理数据->将更新后的数据写回

我有一个包含多个模块的python程序。它们是这样的:

  • 作业类,它是入口点并管理程序的整个流程

  • 任务类,它是要在给定数据上运行的任务的基类。许多专门为不同数据列上的不同计算类型创建的子任务类都是从任务类派生的。假设数据中有10列,每列都有自己的任务进行处理。例如,CurrencyConverterTask可以使用“price”列返回本地货币值等

  • 许多其他模块,如获取数据的连接器、utils模块等,我认为与这个问题无关

  • 程序的一般流程是:从数据库连续获取数据->处理数据->将更新后的数据写回数据库

    我决定在多处理中这样做,因为任务相对简单。他们中的大多数人做一些基本的算术或逻辑运算,在一个进程中运行它需要很长时间,尤其是从一个大数据库中获取数据,并且按顺序处理的速度非常慢

    因此,多处理(mp)代码看起来是这样的(我无法公开整个文件,因此我正在编写一个简化版本,未包含的部分在这里不相关。我已经通过注释它们进行了测试,因此这是实际代码的准确表示):

    整个程序的运行方式如下:
    python3runjob.py

    预期行为:连续的数据流进入
    data\u队列
    ,每个辅助进程获取数据和进程,直到不再有来自游标的数据,此时辅助进程完成,整个程序完成

    这是预期的工作,但不预期的是,系统内存使用量不断攀升,直到系统崩溃。我在这里得到的
    数据没有被复制到任何地方(至少是有意复制的)。我希望在整个程序中内存使用保持稳定。
    data\u队列的长度很少超过1或2,因为进程足够快,可以在可用时获取数据,所以队列不会容纳太多数据


    我猜这里启动的所有进程都是长时间运行的,这与此有关。尽管我可以打印pid,并且如果我在
    top
    命令上遵循pid,数据获取和监视进程不会超过内存使用量的2%。4个工作进程也不会占用大量内存。整个过程的主要过程也是如此。有一个未说明的进程占用了ram的20%以上。它让我非常恼火,我弄不明白它是什么。

    我根本不知道它是如何工作的,因为
    数据队列
    似乎在每个方法中都是局部定义的。@Booboo可能在这个简化版本中,OP每次都是指
    自我数据队列
    。@quamrana你可能是对的,但一般来说,你可以通过删除无关的函数和方法来简化你的文章。但是为了让代码完全错误,我真的不明白为什么有人会这么做。
    class Job():
        def __init__():
            block_size = 100 # process 100 rows at a time
            some_query = "SELECT * IF A > B" # some query to filter data from db
    
        def data_getter():
            # continusouly get data from the db and put it into a queue in blocks
            cursor = Connector.get_data(some_query)
            block = []
    
            for item in cursor:
                block.append(item)
                if len(block) ==block_size:
                    data_queue.put(data)
                    block = []
    
            data_queue.put(None) # this will indicate the worker processors when to stop
    
        def monitor():
            # continuously monitor the system stats
            timer = Timer()
            while (True):
                if timer.time_taken >= 60: # log some stats every 60 seconds
                    print(utils.system_stats())
                    timer.reset()
    
        def task_runner():
            while True:
                # get data from the queue
                # if there's no data, break out of loop
                data = data_queue.get()
                if data is None:
                    break
    
                # run task one by one
                for task in tasks:
                    task.do_something(data)
    
        def run():
            # queue to put data for processing
            data_queue = mp.Queue()
    
            # start a process for reading data from db
            dg = mp.Process(target=self.data_getter).start()
    
            # start a process for monitoring system stats
            mon = mp.Process(target=self.monitor).start()
    
            # get a list of tasks to run
            tasks = [t for t in taskmodule.get_subtasks()]
    
            workers = []
            # start 4 processes to do the actual processing
            for _ in range(4):
                worker = mp.Process(target=task_runner)
                worker.start()
                workers.append(worker)
    
            for w in workers:
                w.join()
    
            mon.terminate() # terminate the monitor process
            dg.terminate() # end the data getting process
    
    
    
    if __name__ == "__main__":
      job = Job()
      job.run()