Я пытаюсь выполнить многопроцессорное программирование с помощью Python. Возьмите алгоритм разделения и покоя, например, Fibonacci
. Поток выполнения программы разветвляется как дерево и выполняется параллельно. Другими словами, мы имеем пример вложенный parallelism.
Из Java я использовал шаблон threadpool для управления ресурсами, так как программа могла быстро разветвляться и создавать слишком много короткоживущих потоков. Один статический (общий) поток можно создать через ExecutorService
.
Я бы ожидал того же для Пул, но кажется, что Объект пула не должен быть глобально распространен. Например, совместное использование пула с помощью multiprocessing.Manager.Namespace()
приведет к ошибке.
объекты пула не могут быть переданы между процессами или маринованными
У меня есть вопрос из двух частей:
- Что мне здесь не хватает; почему не следует делиться пулом между процессами?
- Что такое шаблон для реализации вложенных parallelism в Python?. Если возможно, поддерживая рекурсивную структуру, а не торгуя на итерации.
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();
}
}
Я не уверен, имеет ли это значение здесь, но я игнорирую разницу между "процессом" и "потоком"; для меня они оба означают "виртуализированный процессор". Я понимаю, что цель пула заключается в совместном использовании "пула" или ресурсов. Запуск задач может сделать запрос в пул. По мере выполнения параллельных задач в других потоках эти потоки могут быть восстановлены и назначены для новых задач. Мне не имеет смысла запрещать совместное использование пула, чтобы каждый поток должен создавать свой собственный новый пул, поскольку это, казалось бы, превзошло цель пула потоков.