Системная ошибка в многопроцессорной обработке

Я использую многопроцессорность для выполнения функции для итеративных аргументов. Для слишком длинных массивов в аргументе я получаю следующее сообщение об ошибке:

<multiprocessing.pool.Pool object at 0x545912490>
Exception in thread Thread-2:
Traceback (most recent call last):
  File   "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 342, in _handle_tasks
put(task)
SystemError: NULL result without error in PyObject_Call

Я пытаюсь сравнить образец массивов с другим образцом массивов. Код:

import numpy as np
import multiprocessing

def func(args):
    i=args[0]
    array=args[1]
    sample=args[2]
    for j in np.arange(len(sample)):
        temp=0
        for element in array:
            temp+=len(np.where(sample[j]==element)[0])
    if temp==len(array):
        print i,j       #indices of identical arrays in the samples
    return 0

def compare_samples(a,b):
    iter=len(a)
    pool=multiprocessing.Pool()
    iter_args=[]
    for i in range(0,iter):
        iter_args.append([i,a[i],b])
    print pool
    pool.map(func,iter_args)
    return 0

N=100000000       #error if this number is too large
sample1=np.random.random_integers(0,9,size=(N,10))
sample2=np.random.random_integers(0,9,size=(N,10))

compare_samples(sample1,sample2)

Я нашел аналогичный вопрос (Системная ошибка при запуске подпроцессов с использованием многопроцессорности) , но там решение только для частного случая, я не вижу, как его применить вообще.

Кто-нибудь знает, как исправить ошибку?


person Andy    schedule 23.04.2015    source источник


Ответы (1)


К сожалению, если ответ, на который вы уже ссылались, не работает для вас, я не думаю, что вы найдете другой обходной путь, который позволит вам использовать ваш текущий подход. Вот разговор между парой разработчиков Python, обсуждающих ограничения размера библиотеки многопроцессорной обработки, и это не кажется, что хорошее решение было достигнуто. Похоже, вы упираетесь в ограничения размера, которые на самом деле не имеют «исправления» без изменения самого Python.

Даже если это изменилось к настоящему времени, оно (скорее всего) не будет перенесено на Python 2.7.

Я думаю, у вас есть несколько потенциальных решений:

  1. Разделите возвращаемые данные в рабочих функциях и возвращайте их по частям через в очередь. Возможно, вам потребуется использовать функцию, больше похожую на apply_async вместо map. Это позволит вам контролировать размер ваших данных, которые вы пытаетесь передать между процессами в любой момент времени.

  2. Воспользуйтесь библиотекой mmap и запишите свои результаты в общую память, которая была основной процесс.

  3. Если вы хотите что-то настолько простое, насколько это возможно, и не слишком беспокоитесь о скорости, вы можете просто записать свои результаты в текстовый файл, вернуть имя файла и прочитать его обратно в своем основном процессе.

person skrrgwasme    schedule 25.04.2015