Tôi đang thử lập trình đa xử lý với Python. Lấy một thuật toán phân chia và chinh phục như Fibonacci
chẳng hạn. Luồng thực thi chương trình sẽ phân nhánh như một cây và thực hiện song song. Nói cách khác, chúng tôi có một ví dụ về nested parallelism.Song song lồng nhau trong Python
Từ Java, tôi đã sử dụng mẫu mô hình phân luồng để quản lý tài nguyên, vì chương trình có thể phân nhánh rất nhanh và tạo quá nhiều chuỗi ngắn. Một luồng đơn tĩnh (chia sẻ) có thể được khởi tạo qua ExecutorService
.
Tôi mong đợi tương tự cho Pool, nhưng có vẻ như Pool object is not to be globally shared. Ví dụ: việc chia sẻ Hồ bơi bằng cách sử dụng multiprocessing.Manager.Namespace()
sẽ dẫn đến lỗi.
vật hồ bơi không có thể được thông qua giữa các quá trình hoặc ngâm
Tôi có một câu hỏi 2 phần:
- tôi đang thiếu gì ở đây; tại sao một Pool không được chia sẻ giữa các quá trình?
- Mẫu để triển khai thực hiện song song lồng nhau trong Python là gì? Nếu có thể, hãy duy trì cấu trúc đệ quy và không giao dịch để lặp lại.
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();
}
}
Tôi không chắc chắn nếu vấn đề ở đây, nhưng tôi bỏ qua sự khác biệt giữa "quy trình" và "chủ đề"; với tôi cả hai đều có nghĩa là "bộ xử lý ảo". Sự hiểu biết của tôi là, mục đích của một hồ bơi là để chia sẻ một "hồ bơi" hoặc tài nguyên. Các tác vụ đang chạy có thể đưa ra yêu cầu đối với Hồ bơi. Khi các tác vụ song song hoàn thành trên các chủ đề khác, các luồng đó có thể được khai hoang và gán cho các nhiệm vụ mới. Nó không có ý nghĩa với tôi để không cho phép chia sẻ của hồ bơi, để mỗi thread phải nhanh chóng hồ bơi mới của riêng mình, vì điều đó dường như sẽ đánh bại mục đích của một hồ bơi thread.
Tại sao bạn cần nó được chia sẻ trên toàn cầu?Bạn không thể chứa tất cả bên trong một không gian tên/lớp? –
@InbarRose Vấn đề là trong một hàm đệ quy thực thi cuộc gọi đệ quy bên trong một tiến trình khác, nhóm được chia nhỏ và cũng được gọi bởi tiến trình con. Điều này gây ra vấn đề với hàng đợi do đó nó không hoạt động. Dù sao tôi muốn nhấn mạnh rằng trong Java bạn đang sử dụng * chủ đề *. Với chủ đề không có bất kỳ vấn đề vì không có forking của đối tượng hồ bơi. Tôi tin rằng việc sử dụng một hồ bơi quá trình trong Java sẽ dẫn đến, nhiều hơn hoặc ít hơn, cùng một hành vi. – Bakuriu
@InbarRose Tôi cũng đã thử chứa 'Pool' như một thể hiện lớp và biến tĩnh, nhưng vẫn đạt được cùng một vấn đề. Ví dụ, với 'Pool' và các cuộc gọi đệ quy có trong một lớp đơn, nhưng làm như vậy vẫn dẫn đến cùng một vấn đề:> các đối tượng pool không thể được truyền giữa các tiến trình ... –