多进程发生内存溢出的解决办法

前言

昨天在编写一个多进程程序时,由于自己考虑不周,程序在启动后发生了内存溢出的故障。导致自己的程序卡死崩溃,电脑也陷入了死机黑屏的状态。见识到内存溢出的巨大威害后,觉得自己有必要好好了解一下编写多进程程序时的注意事项,特进行一个总结。

BUG复现

下面的这个程序是自己抽象简化后的:

import multiprocessing
import time
from random import randint
​
​
def func():
    flag = randint(0, 1)
    if flag:
        time.sleep(2)
​
​
if __name__ == '__main__':
    for _ in range(256):
        process = multiprocessing.Process(target=func)
        process.start()
复制代码

抽象化后的程序主体就是这样子的,目标函数会由于情况的不同而选择立即退出或者说等待两秒再退出。

由于需要创建的进程可能会出现两秒的延时,当出现延时的进程十分多的时候就会发生内存溢出的惨案!

解决办法

1. 等待进程运行完毕

既然造成内存溢出的原因是同时运行的进程太多了,那我们就等待一个进程运行完后再运行另外一个进程不久行了吗?

def func():
    flag = randint(0, 1)
    if flag:
        time.sleep(2)
​
​
if __name__ == '__main__':
    for _ in range(256):
        process = multiprocessing.Process(target=func)
        process.start()
        process.join()  # 等待进程运行退出
复制代码

不过这样子和不使用多进程有什么区别吗。。。。真是一个睿(ruo)智的办法!

2. 创建进程池

我们限制一个最大进程数,只要开的进程数小于这个最大进程数,我们就为新任务创建进程,如果开的进程数大于等于了这个最大进程数,我们就让后面的新任务等待前面的任务完成之后再为他创建进程。

这样就能保证我们不会同时创建太多的进程,也就不会导致内存溢出的Bug了:

import multiprocessing
import time
from random import randint
​
​
def func():
    flag = randint(0, 1)
    if flag:
        time.sleep(2)
​
​
if __name__ == '__main__':
    pool = multiprocessing.Pool(multiprocessing.cpu_count())  # 设置进程池最大进程数为电脑CPU数量
    for _ in range(256):
        pool.apply_async(func)
​
    pool.close()
    pool.join()
复制代码

这才真的是一个睿智的办法!

注意事项

  1. 创建多进程时一定要注意任务里有没有会阻塞进程的事件,如果有,一定要给他加一个超时机制!
  2. 一定要限制程序创建的最大进程数!
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'____                           //
//                    .'  \|     |//  `.                         //
//                   /  \|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\  -  /// |   |                       //
//                  | _|  ''---/''  |   |                       //
//                  \  .-__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.____<|>_/___.'  >'"".                  //
//            | | :  `- `.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   _ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.________/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//            佛祖保佑       永不宕机     永无BUG                    //
////////////////////////////////////////////////////////////////////
复制代码

Guess you like

Origin juejin.im/post/7053451688404844581