2013-04-03 40 views
11

Có cách nào đơn giản để sử dụng Multiprocessing để làm tương đương với điều này không?Xử lý đa nhân Python - áp dụng phương pháp lớp vào danh sách các đối tượng

for sim in sim_list: 
    sim.run() 

nơi các yếu tố của sim_list là "mô phỏng" các đối tượng và run() là một phương pháp của lớp mô phỏng mà không sửa đổi các thuộc tính của các đối tượng. Ví dụ:

class simulation: 
    __init__(self): 
    self.state['done']=False 
    self.cmd="program" 
def run(self): 
    subprocess.call(self.cmd) 
    self.state['done']=True 

Tất cả các sim trong sim_list đều độc lập, vì vậy chiến lược không phải là chủ đề an toàn.

Tôi đã thử những điều sau, điều này rõ ràng là thiếu sót bởi vì đối số được truyền qua sâu và không được sửa đổi tại chỗ.

from multiprocessing import Process 

for sim in sim_list: 
    b = Process(target=simulation.run, args=[sim]) 
    b.start() 
    b.join() 
+3

Bạn không muốn tham gia() vào các quy trình của bạn trong vòng lặp, hoặc bạn sẽ chạy chúng sau cái khác thay vì song song. Để trả lời câu hỏi của bạn, bạn có thể gửi một đối tượng multiprocessing.Queue khi bắt đầu Process và sau đó đặt self vào hàng đợi khi hoàn thành. –

+0

Ok để nhận xét về join(). Về việc sử dụng Hàng đợi, tôi không chắc chắn cách thức này được cho là hoạt động. Chẳng phải đối tượng sim của tôi sẽ được truyền qua sâu không? – calys

+0

@calys Trên cửa sổ, bạn sẽ nhận được một 'PicklingError' vì bạn đang cố gắng để chọn một phương pháp, trên UNIX không có" deepcopy ", chỉ đơn giản là mỗi quá trình có được một bản sao hoàn hảo của toàn bộ không gian địa chỉ. Bạn phải thay thế sự thay đổi trạng thái trong cá thể bằng một số giao tiếp interprocess rõ ràng. – Bakuriu

Trả lời

11

Một cách để làm những gì bạn muốn là phải có lớp máy tính của bạn (simulation trong trường hợp của bạn) là một lớp con của Process. Khi được khởi tạo đúng, các cá thể của lớp này sẽ chạy trong các tiến trình riêng biệt và bạn có thể đặt một nhóm chúng từ một danh sách giống như bạn muốn.

Dưới đây là một ví dụ, xây dựng trên những gì bạn đã viết ở trên:

import multiprocessing 
import os 
import random 

class simulation(multiprocessing.Process): 
    def __init__(self, name): 
     # must call this before anything else 
     multiprocessing.Process.__init__(self) 

     # then any other initialization 
     self.name = name 
     self.number = 0.0 
     sys.stdout.write('[%s] created: %f\n' % (self.name, self.number)) 

    def run(self): 
     sys.stdout.write('[%s] running ... process id: %s\n' 
         % (self.name, os.getpid())) 

     self.number = random.uniform(0.0, 10.0) 
     sys.stdout.write('[%s] completed: %f\n' % (self.name, self.number)) 

Sau đó chỉ cần tạo ra một danh sách các đối tượng và bắt đầu mỗi người với một vòng lặp:

sim_list = [] 
sim_list.append(simulation('foo')) 
sim_list.append(simulation('bar')) 

for sim in sim_list: 
    sim.start() 

Khi bạn chạy này, bạn nên xem từng đối tượng chạy trong tiến trình riêng của nó. Đừng quên gọi Process.__init__(self) là điều đầu tiên trong quá trình khởi tạo lớp học của bạn, trước bất cứ điều gì khác.

Rõ ràng là tôi chưa bao gồm bất kỳ liên lạc truyền thông nào trong ví dụ này; bạn sẽ phải thêm rằng nếu tình huống của bạn yêu cầu nó (nó không rõ ràng từ câu hỏi của bạn cho dù bạn cần nó hay không).

Cách tiếp cận này phù hợp với tôi và tôi không biết bất kỳ hạn chế nào. Nếu có ai biết về những mối nguy hiểm tiềm ẩn mà tôi đã bỏ qua, xin vui lòng cho tôi biết.

Tôi hy vọng điều này sẽ hữu ích.

+1

Cảm ơn rất nhiều. Nó hoạt động :) – calys

+0

Câu trả lời tuyệt vời, cảm ơn –

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