Python内存分配错误

时间:2017-04-16 17:16:14

标签: python memory timeout subprocess

我在python中遇到内存分配问题,这看起来很奇怪,因为我认为我的脚本应该使用常量内存。我使用子进程运行外部脚本,然后记录结果。有时脚本需要太长时间,因此我设置了超时异常。这就是我所拥有的:

class Timeout():
    """Timeout class using ALARM signal."""
    class Timeout(Exception):
        pass

    def __init__(self, sec):
        self.sec = sec

    def __enter__(self):
        signal.signal(signal.SIGALRM, self.raise_timeout)
        signal.alarm(self.sec)

    def __exit__(self, *args):
        signal.alarm(0)    # disable alarm

    def raise_timeout(self, *args):
        raise Timeout.Timeout()

def simulate(Length, Time, parameters, conditions):
    args = tuple(list(np.append(parameters, np.append([Length, Time], conditions))))
    cmd = './simulate.m %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % args
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)

    try:
        with Timeout(2):
            string = proc.stdout.read()
            result = (float(re.sub(r'\*\^', 'e', string)))
    except ValueError:
        print "ValueError", parameters
        result = np.linalg.norm(parameters) * 100.0
    except Timeout.Timeout:
        print "TimeoutException", parameters
        result = np.linalg.norm(parameters) * 100.0
    except:
        print "Other Exception"
        result = np.linalg.norm(parameters) * 100.0
    finally:
        proc.terminate()

    return result

我调用它并在循环中打印结果:

iters = 0

while iters < 100000:
    conditions = random_conditions()
    parameters = (np.random.rand(7) * 10) - 5
    length = np.random.randint(500 - 75) + 75
    time = np.random.randint((7200 - 3600) * 2) + 3600
    fraction = simulate(length, 7200, parameters, conditions)

    if fraction <= 1.0:
        print ','.join(map(lambda num: str(num), np.concatenate(([time], [length], parameters, conditions, [fraction]))))
        iters += 1

大约500次尝试后,我收到内存分配错误:

Traceback (most recent call last):   File "Data_Generation.py", line 27, in <module>
    fraction = simulate(length, 7200, parameters, conditions)   File "/home/***/Documents/Lab_Program/approximator/data_generation/simulation_utils.py", line 27, in simulate
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)   File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)   File "/usr/lib/python2.7/subprocess.py", line 1223, in _execute_child
    self.pid = os.fork() OSError: [Errno 12] Cannot allocate memory

为什么会这样?我关闭进程并在每次迭代时打印结果。这不应该是恒定的记忆吗?它似乎发生在超时错误附近。

编辑*我尝试按照此答案中的建议杀死子进程。而不是使用proc.terminate()。它走得更远(虽然这可能只是随机的)并且遇到了同样的错误。

编辑**我以极其苛刻的方式解决了这个问题。我知道可能生成的任何进程都有一个与特定正则表达式匹配的名称。我只是使用pgkill -9 -f regex来杀死所有未被杀死的进程。我知道这些过程不会产生孩子,所以这有点安全。如果有人对清洁解决方案有任何见解,我很乐意听到。

0 个答案:

没有答案