functools.partial() und multiprocessing

Moin! Ich arbeite derzeit mit partial() und dem multiprocessing-Modul. Unter 2.7 und 3.2 ist alles rosig. Dummerweise muss das Skript auch mit 2.6.5 laufen. Trivialbeispiel: from functools import partial from multiprocessing import Pool def fun(a, b): return a+b fun2=partial(fun, b=2) pool = Pool(5) results = pool.map(fun2, range(1)) print len(results) Das liefert, wie zu erwarten, "1", wenn man 2.7.x oder 3.2.x benuztzt. Damit es echtes multiprocessing wird, kann man auch range(100) benutzen, am Problem ändert sich nichts (nur wird der stacktrace unübersichtlich). Mit 2.6.5 passiert das hier: Process PoolWorker-1: Traceback (most recent call last): File "/usr/lib/python2.6/multiprocessing/process.py", line 232, in _bootstrap self.run() File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run self._target(*self._args, **self._kwargs) File "/usr/lib/python2.6/multiprocessing/pool.py", line 57, in worker task = get() File "/usr/lib/python2.6/multiprocessing/queues.py", line 352, in get return recv() TypeError: type 'partial' takes at least one argument Und das Programm terminiert auch nicht. Mir ist nicht ganz klar, ob ich partial/multiprocessing nur falsch benutze oder das, was ich will, mit 2.6.5 einfach nicht geht. Das Problem ohne partial() zu lösen ginge auch, wäre aber deutlich hässlicher. Gruss, Tobias

Tobias Klausmann wrote:
Moin!
Ich arbeite derzeit mit partial() und dem multiprocessing-Modul. Unter 2.7 und 3.2 ist alles rosig. Dummerweise muss das Skript auch mit 2.6.5 laufen.
Trivialbeispiel: from functools import partial from multiprocessing import Pool
def fun(a, b): return a+b
fun2=partial(fun, b=2) pool = Pool(5) results = pool.map(fun2, range(1))
print len(results)
Das liefert, wie zu erwarten, "1", wenn man 2.7.x oder 3.2.x benuztzt.
Damit es echtes multiprocessing wird, kann man auch range(100) benutzen, am Problem ändert sich nichts (nur wird der stacktrace unübersichtlich).
Mit 2.6.5 passiert das hier:
Process PoolWorker-1: Traceback (most recent call last): File "/usr/lib/python2.6/multiprocessing/process.py", line 232, in _bootstrap self.run() File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run self._target(*self._args, **self._kwargs) File "/usr/lib/python2.6/multiprocessing/pool.py", line 57, in worker task = get() File "/usr/lib/python2.6/multiprocessing/queues.py", line 352, in get return recv() TypeError: type 'partial' takes at least one argument
Und das Programm terminiert auch nicht.
Mir ist nicht ganz klar, ob ich partial/multiprocessing nur falsch benutze oder das, was ich will, mit 2.6.5 einfach nicht geht. Das Problem ohne partial() zu lösen ginge auch, wäre aber deutlich hässlicher.
Ich vermute, dass das Problem darin besteht, dass partial-Objekte erst ab 2.7 serialisierbar sind. Unterstützung für pickle lässt sich aber nachrüsten: from functools import partial import copy_reg def pickle_partial(p): return unpickle_partial, (p.func, p.args, p.keywords) def unpickle_partial(func, args, keywords): return partial(func, *args, **keywords) copy_reg.pickle(partial, pickle_partial)
participants (2)
-
Peter Otten
-
Tobias Klausmann