Странная ошибка расслоения при использовании многопроцессорной обработки - PullRequest
2 голосов
/ 23 декабря 2009

Я получаю следующую ошибку при использовании многопроцессорной обработки:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 477, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.6/multiprocessing/pool.py", line 282, in _handle_results
    task = get()
UnpicklingError: NEWOBJ class argument has NULL tp_new

Я понятия не имею, что это значит, хотя на уровне Си это звучит как-то не так. Кто-нибудь может пролить свет на это?

ОБНОВЛЕНИЕ : Хорошо, поэтому я понял, как это исправить. Но я все еще немного озадачен. Я возвращаю экземпляр этого класса:

class SpecData(object):
    def __init__(self, **kwargs):
        self.__dict__.update(**kwargs)
    def to_dict(self):
        return self.__dict__

Если я возвращаю экземпляр этого объекта, я получаю ошибку. Однако если я позвоню to_dict и верну словарь, это сработает. Что я делаю не так?

Ответы [ 3 ]

3 голосов
/ 30 декабря 2009

Попробуйте использовать модуль pickle вместо модуля cPickle - pickle написан на чистом Python и часто выдает более полезные сообщения об ошибках, чем cPickle. (Хотя иногда мне приходилось делать локальную копию pickle.py и добавлять несколько отладочных операторов printf рядом с местом ошибки, чтобы выяснить проблему.)

Как только вы обнаружите проблему, вы можете переключиться обратно на cpickle.

(Я не очень знаком с модулем многопроцессорной обработки, поэтому я не уверен, выполняете ли вы процесс засолки или это так. Если это так, то самый простой способ заставить его использовать команду pickle, а не cpickle, может перед импортом модуля многопроцессорной / многопоточной обработки необходимо выполнить некоторые операции по исправлению ошибок: import sys, pickle; sys.modules['cPickle']=pickle)

2 голосов
/ 23 октября 2012

Я думаю, что это проблема с возможностью выбора / невидимости некоторых функций Python. Смотрите этот пост:

http://khinsen.wordpress.com/2012/02/06/teaching-parallel-computing-in-python/

У меня были похожие проблемы при использовании django-celery (который использует модуль многопроцессорной обработки). Если мой код задачи выдает ошибки, которые сами по себе не могут быть извлечены, это исключение мультипроцессора / рассола скрывает информацию. Поскольку я не нашел лучшего способа распространения ошибок, я прибегаю к отладке логов в своем коде задачи, чтобы выследить их. Я, вероятно, должен быть более умным в отношении того, что я передаю в очередь (защитите от помещения исключений в очередь сообщений, чтобы многопроцессорный модуль не пытался их выбирать / удалять).

В приведенном выше случае вам может потребоваться убедиться, что SpecData.__dict__ пригоден для продажи. Смотри http://docs.python.org/library/pickle.html#pickle-protocol

0 голосов
/ 23 декабря 2009

Я сделал потокобезопасность в C ++, Java и Delphi, но не в Python, поэтому возьмите мои комментарии с частичкой соли.

На этой странице, посвященной Python и Thread-Safety , конкретно упоминается о том, что словарь должен быть атомарным и поточно-ориентированным. Возможно, ваша ссылка на ваш пользовательский класс не является поточно-ориентированной? Попробуйте добавить некоторые из рекомендуемых механизмов блокировки, если вы все равно предпочитаете передавать пользовательский класс контейнера между двумя потоками.

Меня удивляет, что в других результатах поиска подчеркивается, что Python полностью поточно-ориентирован. Python самостоятельно документирует , что блокировки и другие механизмы предоставляются для помощи в многопоточных приложениях, поэтому похоже, что в этом случае неправильные интернет-сети (это даже случается ??).

Еще один вопрос StackOverflow о безопасности Python и потоке .

...