Ich probiere Multiprozessor-Programmierung mit Python aus. Nehmen Sie einen Divide and Conquer-Algorithmus wie zum Beispiel Fibonacci
. Der Programmablauf der Ausführung verzweigt sich wie ein Baum und wird parallel ausgeführt. Mit anderen Worten, wir haben ein Beispiel für nested parallelism.Verschachtelte Parallelität in Python
Von Java habe ich ein Threadpoolmuster verwendet, um Ressourcen zu verwalten, da das Programm sehr schnell verzweigen und zu viele kurzlebige Threads erstellen kann. Ein einzelner statischer (gemeinsamer) Threadpool kann über ExecutorService
instanziiert werden.
Ich würde das gleiche für Pool erwarten, aber es scheint, dass Pool object is not to be globally shared. Wenn Sie beispielsweise den Pool mit multiprocessing.Manager.Namespace()
freigeben, wird der Fehler angezeigt.
Pool-Objekte können nicht zwischen Prozessen oder gebeizt
Ich habe einen 2-teiligen Frage übergeben werden:
- Was ich hier fehlt; Warum sollte kein Pool zwischen Prozessen geteilt werden?
- Was ist ein Muster für die Implementierung verschachtelter Parallelität in Python? Wenn möglich, rekursive Struktur beibehalten und nicht für Iteration handeln.
from concurrent.futures import ThreadPoolExecutor
def fibonacci(n):
if n < 2:
return n
a = pool.submit(fibonacci, n - 1)
b = pool.submit(fibonacci, n - 2)
return a.result() + b.result()
def main():
global pool
N = int(10)
with ThreadPoolExecutor(2**N) as pool:
print(fibonacci(N))
main()
Java
public class FibTask implements Callable<Integer> {
public static ExecutorService pool = Executors.newCachedThreadPool();
int arg;
public FibTask(int n) {
this.arg= n;
}
@Override
public Integer call() throws Exception {
if (this.arg > 2) {
Future<Integer> left = pool.submit(new FibTask(arg - 1));
Future<Integer> right = pool.submit(new FibTask(arg - 2));
return left.get() + right.get();
} else {
return 1;
}
}
public static void main(String[] args) throws Exception {
Integer n = 14;
Callable<Integer> task = new FibTask(n);
Future<Integer> result =FibTask.pool.submit(task);
System.out.println(Integer.toString(result.get()));
FibTask.pool.shutdown();
}
}
Ich bin mir nicht sicher, ob es hier ankommt, aber ich bin der Unterschied zwischen "Prozess" und "Faden" zu ignorieren; Für mich bedeuten beide "virtualisierter Prozessor". Mein Verständnis ist, der Zweck eines Pools ist die gemeinsame Nutzung eines "Pools" oder Ressourcen. Laufende Aufgaben können eine Anfrage an den Pool stellen. Wenn parallele Tasks in anderen Threads ausgeführt werden, können diese Threads zurückgewonnen und neuen Tasks zugewiesen werden. Es macht für mich keinen Sinn, das Teilen des Pools zu verbieten, so dass jeder Thread seinen eigenen neuen Pool instanziieren muss, da dies den Zweck eines Thread-Pools zu besiegen scheint.
Warum brauchen Sie es global zu teilen?Kannst du das nicht alles in einem Namespace/Klasse enthalten? –
@InbarRose Das Problem besteht darin, dass in einer rekursiven Funktion, die den rekursiven Aufruf in einem anderen Prozess ausführt, der Pool verzweigt ist und auch vom Subprozess aufgerufen wird. Dies verursacht Probleme mit den Warteschlangen, daher funktioniert es nicht. Jedenfalls möchte ich betonen, dass Sie in Java * threads * verwenden. Bei Threads gibt es keine Probleme, da das Pool-Objekt nicht verzweigt wird. Ich glaube, dass die Verwendung eines Prozesspools in Java zu mehr oder weniger demselben Verhalten führen würde. – Bakuriu
@InbarRose Ich habe auch versucht, 'Pool' als Klasseninstanz und statische Variable zu enthalten, aber immer noch dasselbe Problem zu erreichen. Zum Beispiel mit 'Pool' und den rekursiven Aufrufen innerhalb einer einzelnen Klasse, aber dies führt immer noch zum selben Problem:> Pool-Objekte können nicht zwischen Prozessen übergeben werden ... –