2013-05-20 3 views
1
import multiprocessing 
import time 
import pycurl 

class Bot(multiprocessing.Process): 
    def __init__(self): 
     multiprocessing.Process.__init__(self)  
     self.c = pycurl.Curl() 

    def run(self): 
     pass 

if __name__ == '__main__': 
    Bot().start()  

Этот код хорошо работает на Ubuntu 13.04 x64, но не работает в Windows 7 x64/Server 2008 x64. Я использую pyCurl 7.19.0 и Python 2.7. Ошибка:PyCurl. Ошибка «Невозможно рассортировать объект Curl» в Windows x64

Z:\bot>python test.py 
Traceback (most recent call last): 
    File "test.py", line 74, in <module> 
    Bot().start() 
    File "C:\Python27\lib\multiprocessing\process.py", line 104, in start 
    self._popen = Popen(self) 
    File "C:\Python27\lib\multiprocessing\forking.py", line 244, in __init__ 
    dump(process_obj, to_child, HIGHEST_PROTOCOL) 
    File "C:\Python27\lib\multiprocessing\forking.py", line 167, in dump 
    ForkingPickler(file, protocol).dump(obj) 
    File "C:\Python27\lib\pickle.py", line 224, in dump 
    self.save(obj) 
    File "C:\Python27\lib\pickle.py", line 331, in save 
    self.save_reduce(obj=obj, *rv) 
    File "C:\Python27\lib\pickle.py", line 419, in save_reduce 
    save(state) 
    File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Python27\lib\pickle.py", line 649, in save_dict 
    self._batch_setitems(obj.iteritems()) 
    File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems 
    save(v) 
    File "C:\Python27\lib\pickle.py", line 313, in save 
    (t.__name__, obj)) 
pickle.PicklingError: Can't pickle 'Curl' object: <pycurl.Curl object at 0x00000 
00002360478> 

Z:\bot>Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
    File "C:\Python27\lib\multiprocessing\forking.py", line 347, in main 
    self = load(from_parent) 
    File "C:\Python27\lib\pickle.py", line 1378, in load 
    return Unpickler(file).load() 
    File "C:\Python27\lib\pickle.py", line 858, in load 
    dispatch[key](self) 
    File "C:\Python27\lib\pickle.py", line 880, in load_eof 
    raise EOFError 
EOFError 

Почему это происходит?

+0

Несмотря на то, что 'pycurl' легко создает для меня на linux, мне трудно работать над окнами; Предварительно установленные установщики окон останавливаются на python2.5. Есть ли определенный протокол, который вы пытаетесь использовать, поддерживает только 'pycurl'? Существует много альтернатив. – SingleNegationElimination

+0

@TokenMacGuy нет, я собирался использовать его для небольшого преимущества скорости. – clumpter

+0

Хм ... что-нибудь, что вы могли бы сделать с 'libcurl', будет привязано к IO, вы используете его для соединения с локальным хостом? – SingleNegationElimination

ответ

1

В системах Posix, multiprocessing работает с использованием fork(), что системного вызова клонирует запущенный процесс, и все его состояния (в том числе таких вещей, как экземпляры сложных классов, такие как pycurl.Curl).

Windows, не имеет fork(), или ничего подобного, так что multiprocessing разжигает новый питона интерпретатор для каждого дочернего процесса, с помощью специальной функции-заглушки, которая прислушивается к родительскому процессу и воссоздает состояние так, что она выглядит так же, как ему было бы использовано fork(). Ключевой метод, используемый multiprocessing, заключается в том, что он воссоздает каждый объект в дочернем процессе, начиная с родительского процесса, по мере их использования. Это работает путем преобразования объектов в представление байт-кода (с использованием модуля pickle), отправки их по каналу дочернему элементу и последующего преобразования их обратно в объекты python.

Для большинства видов объектов python это прекрасно работает и прозрачно для вас. Существует ряд очевидных вещей, когда это не может работать; открытые файлы не могут быть переданы таким образом; а также состояние объектов библиотеки, отличных от python, которые ничего не знают о системе pickle. К сожалению, pycurl - это немного и то и другое.