2012-10-19 21 views
6

Tôi có một kịch bản như thế này: Tôi đã tạo một đối tượng của phần tử lớp có chứa một semaphore.Đa xử lý Python, chuyển một tham chiếu đối tượng chứa một semaphore

import multiprocessing as mpr 

class Element(object): 
    def __init__(self): 
     self.sem = mpr.Semaphore() 
     self.xyz = 33 

def fun(ch): 
    a = ch.recv() 
    print(a[0]) 
    print(a[1].xyz) 
    a[1].xyz = 99 
    print(a[1].xyz) 


el = Element() 

(pa , ch) = mpr.Pipe() 
proc = mpr.Process(target=fun , args=(ch,)) 

proc.start() 
pa.send([ "Hallo" , el ]) 

print(el.xyz) 

proc.join() 

mã trở lại này lỗi này:

File "/usr/lib/python2.7/multiprocessing/forking.py", line 51, in assert_spawning 
    ' through inheritance' % type(self).__name__ 
RuntimeError: Semaphore objects should only be shared between processes through inheritance 

Nhưng nếu tôi loại bỏ các semaphore từ việc kê khai của Element mã hoạt động, nhưng giá trị được gán cho một [1] .xyz sẽ bị mất.

Bây giờ tôi cần phải đồng bộ hóa một bộ sưu tập lớn đối tượng thông qua bán kết và đa xử lý. Vì vậy, có một số phương pháp để thiết lập một semaphore trong mọi đối tượng và chỉ chuyển tham chiếu đến đối tượng chính?

import multiprocessing as mpr 

class Element(object): 
    def __init__(self): 
     self.xyz = 33 

def fun(ch): 
    a = ch.recv() 
    print(a[0]) 
    print(a[1].xyz) 
    a[1].xyz = 99 
    print(a[1].xyz) 


el = Element() 

(pa , ch) = mpr.Pipe() 
proc = mpr.Process(target=fun , args=(ch,)) 

proc.start() 
pa.send([ "Hallo" , el ]) 

print(el.xyz) 

proc.join() 

Phiên bản thứ hai không tạo ra lỗi, nhưng giá trị được gán cho a[1].xyz = 99 sẽ bị mất trong quá trình chính.

+0

Lỗi của bạn là rõ ràng nó nói rằng semaphore nên là một thuộc tính của quá trình và bạn không thể gửi nó cho anh ta. Vì vậy, về cơ bản bạn cần phải kế thừa từ quá trình và xác định một 'chạy' vv ... Nhưng đó là cách che khuất những gì bạn đang cố gắng làm. –

+0

Có lẽ bạn có thể phân bổ một mảng lớn các semaphores lúc bắt đầu và vượt qua chỉ giữ một sem_index bên trong đối tượng Element? – cdleonard

+0

Vượt qua một mảng sao chép cùng một vấn đề theo một cách khác, vấn đề là với semaphore, không phải trong container. – Giggi

Trả lời

13

Tôi không nghĩ bạn hiểu cách hoạt động của mô-đun multiprocessing.

Khi bạn gửi một thứ gì đó qua đường ống, nó sẽ được chọn và sau đó được bỏ tạm dừng trong tiến trình con. Điều này có nghĩa là quy trình con thực sự có một bản sao của đối tượng gốc! Đó là lý do tại sao thay đổi bị "mất". Thêm một semaphore sẽ không thay đổi bất cứ điều gì.

Nếu bạn muốn một đối tượng trong bộ nhớ dùng chung, bạn nên sử dụng multiprocessing.Value, mặc dù điều này không xử lý các loại tùy ý. Có lẽ multiprocessing.Manager là những gì bạn đang tìm kiếm.

Một cách khác là gửi phản hồi đến quy trình chính cung cấp đối tượng đã sửa đổi.

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