Ich versuche, Systembefehle zu verarbeiten, kann sie jedoch nicht mit einem einfachen Programm zum Laufen bringen. Die Funktion runit (cmd) funktioniert aber einwandfrei ...
#!/usr/bin/python3
from subprocess import call, run, PIPE,Popen
from multiprocessing import Pool
import os
pool = Pool()
def runit(cmd):
proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
return proc.stdout.read()
#print(runit('ls -l'))
it = []
for i in range(1,3):
it.append('ls -l')
results = pool.map(runit, it)
Es gibt aus:
Process ForkPoolWorker-1:
Process ForkPoolWorker-2:
Traceback (most recent call last):
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
self.run()
File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.5/multiprocessing/pool.py", line 108, in worker
task = get()
File "/usr/lib/python3.5/multiprocessing/queues.py", line 345, in get
return ForkingPickler.loads(res)
AttributeError: Can't get attribute 'runit' on <module '__main__' from './syscall.py'>
File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
self.run()
File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.5/multiprocessing/pool.py", line 108, in worker
task = get()
File "/usr/lib/python3.5/multiprocessing/queues.py", line 345, in get
return ForkingPickler.loads(res)
AttributeError: Can't get attribute 'runit' on <module '__main__' from './syscall.py'>
Dann wartet es irgendwie und tut nichts, und wenn ich ein paar Mal Strg + C drücke, spuckt es aus:
^CProcess ForkPoolWorker-4:
Process ForkPoolWorker-6:
Traceback (most recent call last):
File "./syscall.py", line 17, in <module>
Process ForkPoolWorker-5:
results = pool.map(runit, it)
File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map
...
buf = self._recv(4)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 379, in _recv
chunk = read(handle, remaining)
KeyboardInterrupt
Ich bin mir nicht sicher, da das Problem, das ich kenne, mit Windows zusammenhängt (und ich keinen Zugriff auf die Linux-Box habe, um es erneut zu verarbeiten), aber um portabel zu sein, müssen Sie Ihre multiprocessing-abhängigen Befehle einbinden, da if __name__=="__main__"
dies zu Konflikten führt Die Art und Weise, wie Python die Prozesse erzeugt: Dieses feste Beispiel läuft unter Windows einwandfrei (und sollte auch auf anderen Plattformen einwandfrei funktionieren):
from multiprocessing import Pool
import os
def runit(cmd):
proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
return proc.stdout.read()
#print(runit('ls -l'))
it = []
for i in range(1,3):
it.append('ls -l')
if __name__=="__main__":
# all calls to multiprocessing module are "protected" by this directive
pool = Pool()
(Wenn ich die Fehlermeldungen genauer studiere, bin ich mir jetzt ziemlich sicher, dass ein Umzug pool = Pool()
nach der Deklaration von runit
das Problem auch unter Linux beheben würde, aber das Einschließen von __main__
Fixes + macht es portabel.)
Beachten Sie jedoch, dass Ihre Mehrfachverarbeitung nur einen neuen Prozess erstellt, sodass Sie mit Thread-Pools ( Threading-Pool ähnlich dem Multiprocessing-Pool? ) Besser dran sind : Threads, die Prozesse wie folgt erstellen :
from multiprocessing.pool import ThreadPool # uses threads, not processes
import os
def runit(cmd):
proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
return proc.stdout.read()
it = []
for i in range(1,3):
it.append('ls -l')
if __name__=="__main__":
pool = ThreadPool() # ThreadPool instead of Pool
results = pool.map(runit, it)
print(results)
results = pool.map(runit, it)
print(results)
Die letztere Lösung ist leichter und weniger problemanfällig (Multiprocessing ist ein heikles Modul). Sie können unter anderem mit Objekten, gemeinsam genutzten Daten usw. arbeiten, ohne dass ein Manager
Objekt erforderlich ist
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen