Zagnieżdżona równoległość w Pythonie

Wypróbowuję programowanie wieloprocesorowe w Pythonie. Weź algorytm dziel i rządź jakFibonacci na przykład. Przepływ wykonywania programu rozgałęziłby się jak drzewo i wykonał równolegle. Innymi słowy, mamy przykładzagnieżdżona równoległość.

Z Javy korzystałem z wzorca threadpool do zarządzania zasobami, ponieważ program mógł bardzo szybko rozgałęziać się i tworzyć zbyt wiele wątków krótkotrwałych. Pojedynczy statyczny puli wątków można udostępnić za pośrednictwemExecutorService.

Tego samego oczekiwałbymBasen, ale wygląda na toObiekt Pool nie może być globalnie udostępniany. Na przykład udostępnianie puli za pomocąmultiprocessing.Manager.Namespace() doprowadzi do błędu.

obiekty puli nie mogą być przekazywane między procesami lub marynowane

Mam pytanie 2-częściowe:

Czego mi tu brakuje; dlaczego nie powinno się dzielić puli między procesy?Co to jestwzorzec do implementacji zagnieżdżonej równoległości w Pythonie? Jeśli to możliwe, utrzymywanie struktury rekurencyjnej i nie handlowanie nią dla iteracji.
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()

Jawa

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();            
  }    

}

Nie jestem pewien, czy ma to znaczenie tutaj, ale ignoruję różnicę między „procesem” a „wątkiem”; dla mnie oba oznaczają „zwirtualizowany procesor”. Rozumiem, że celem puli jest dzielenie się „pulą” lub zasobami. Uruchomione zadania mogą wysyłać żądania do puli. W miarę wykonywania równoległych zadań na innych wątkach można je odzyskać i przypisać do nowych zadań. Nie ma sensu odmawianie współużytkowania puli, tak aby każdy wątek tworzył swoją własną pulę, ponieważ wydaje się, że pokonuje to cel puli wątków.

questionAnswers(2)

yourAnswerToTheQuestion