2010-08-10 39 views
6

Tôi có cấu trúc dữ liệu phức tạp (loại do người dùng xác định) mà trên đó một số lượng lớn các phép tính độc lập được thực hiện. Cấu trúc dữ liệu về cơ bản là không thay đổi. Tôi nói về cơ bản, bởi vì mặc dù giao diện trông bất biến, nội bộ một số đánh giá lười biếng đang xảy ra. Một số thuộc tính được tính toán lazily được lưu trữ trong các từ điển (giá trị trả về của các hàm tốn kém theo tham số đầu vào). Tôi muốn sử dụng mô-đun Pythons multiprocessing để song song các tính toán này. Có hai câu hỏi trong đầu tôi.Chia sẻ dữ liệu giữa các quy trình trong Python

  1. Làm cách nào để chia sẻ cấu trúc dữ liệu tốt nhất giữa các quy trình?
  2. Có cách nào để xử lý vấn đề đánh giá lười biếng mà không sử dụng khóa (nhiều quy trình viết cùng một giá trị) không?

Cảm ơn trước mọi câu trả lời, nhận xét hoặc câu hỏi khai sáng!

+0

Bạn đang nói chuyện phức tạp đến mức nào? Khi một 'phép tính độc lập' được gửi đi, bạn có biết trước khi bắt đầu các thuộc tính lười biếng nào cần thiết không? – MattH

+0

Vấn đề về cơ bản là việc xác thực chéo một lần bỏ qua trên một tập hợp lớn các mẫu dữ liệu. Nó mất khoảng hai giờ trên máy tính của tôi trên một lõi đơn, nhưng tôi có quyền truy cập vào một máy với 24 lõi và muốn tận dụng sức mạnh đó. Tôi không biết trước các thuộc tính nào sẽ là cần thiết bởi một phép tính duy nhất, nhưng tôi biết rằng cuối cùng (trên tất cả các tính toán) tất cả các thuộc tính sẽ là cần thiết, vì vậy tôi có thể tải chúng lên phía trước (sẽ phải kiểm tra mặc dù). –

Trả lời

8

Làm cách nào để chia sẻ cấu trúc dữ liệu tốt nhất giữa các quy trình?

Đường ống.

origin.py | process1.py | process2.py | process3.py 

Phá vỡ chương trình của bạn để mỗi phép tính là một quá trình riêng biệt của biểu mẫu sau.

def transform1(piece): 
    Some transformation or calculation. 

Để thử nghiệm, bạn có thể sử dụng nó như thế này.

def t1(iterable): 
    for piece in iterable: 
     more_data = transform1(piece) 
     yield NewNamedTuple(piece, more_data) 

Để tái tạo toàn bộ phép tính trong một quy trình, bạn có thể thực hiện việc này.

for x in t1(t2(t3(the_whole_structure))): 
    print(x) 

Bạn có thể quấn từng chuyển đổi bằng một chút tệp I/O. Pickle hoạt động tốt cho điều này, nhưng các biểu diễn khác (như JSON hoặc YAML) cũng hoạt động tốt.

while True: 
    a_piece = pickle.load(sys.stdin) 
    more_data = transform1(a_piece) 
    pickle.dump(NewNamedTuple(piece, more_data)) 

Mỗi bước xử lý sẽ trở thành một quy trình cấp hệ điều hành độc lập. Chúng sẽ chạy đồng thời và sẽ - ngay lập tức - tiêu thụ tất cả các tài nguyên ở cấp hệ điều hành.

Có cách nào để xử lý vấn đề đánh giá lười biếng mà không sử dụng khóa (nhiều quy trình viết cùng một giá trị) không?

Đường ống.

+0

Wow, câu trả lời giải quyết hai vấn đề mà ngay cả trong câu hỏi của tôi (làm thế nào để gửi một đối tượng phức tạp đến quá trình khác, làm thế nào để làm điều này trong python khi multiprocessing-module không có sẵn)! –

+0

Vấn đề là quản lý quy trình cấp hệ điều hành (bộ đệm chia sẻ) là (a) đơn giản hơn và (b) có thể nhanh như các kỹ thuật đa luồng, chia sẻ mọi thứ phức tạp hơn. –

Các vấn đề liên quan