2009-07-02 34 views
5

Tôi có câu hỏi về tài nguyên được chia sẻ có xử lý tệp giữa các quy trình. Đây là mã thử nghiệm của tôi:Chia sẻ các đối tượng có thuộc tính xử lý tệp giữa các quá trình

from multiprocessing import Process,Lock,freeze_support,Queue 
import tempfile 
#from cStringIO import StringIO 

class File(): 
    def __init__(self): 
     self.temp = tempfile.TemporaryFile() 
     #print self.temp 

    def read(self): 
     print "reading!!!" 
     s = "huanghao is a good boy !!" 
     print >> self.temp,s 
     self.temp.seek(0,0) 

     f_content = self.temp.read() 
     print f_content 

class MyProcess(Process): 
    def __init__(self,queue,*args,**kwargs): 
     Process.__init__(self,*args,**kwargs) 
     self.queue = queue 

    def run(self): 
     print "ready to get the file object" 
     self.queue.get().read() 
     print "file object got" 
     file.read() 

if __name__ == "__main__": 
    freeze_support() 
    queue = Queue() 
    file = File() 

    queue.put(file) 
    print "file just put" 

    p = MyProcess(queue) 
    p.start() 

Sau đó, tôi nhận được một KeyError như dưới đây:

file just put 
ready to get the file object 
Process MyProcess-1: 
Traceback (most recent call last): 
    File "D:\Python26\lib\multiprocessing\process.py", line 231, in _bootstrap 
    self.run() 
    File "E:\tmp\mpt.py", line 35, in run 
    self.queue.get().read() 
    File "D:\Python26\lib\multiprocessing\queues.py", line 91, in get 
    res = self._recv() 
    File "D:\Python26\lib\tempfile.py", line 375, in __getattr__ 
    file = self.__dict__['file'] 
KeyError: 'file' 

Tôi nghĩ khi tôi đặt các đối tượng File() vào hàng đợi, các đối tượng đã tuần tự hóa và xử lý tập tin không thể được tuần tự hóa, vì vậy, tôi đã nhận được KeyError:

Bất kỳ ai cũng có ý tưởng về điều đó? nếu tôi muốn chia sẻ các đối tượng với thuộc tính xử lý tệp, tôi nên làm gì?

Trả lời

7

Tôi phải đối tượng (theo chiều dài, sẽ không vừa trong một commentl ;-) để xác nhận lặp đi lặp lại của @ Mark rằng xử lý tập tin chỉ có thể không được "thông qua xung quanh giữa các quá trình chạy" - điều này chỉ đơn giản là không đúng sự thật trong thực tế, hệ điều hành hiện đại, như, oh, nói, Unix (biến thể BSD miễn phí, MacOSX, và Linux, bao gồm - hmmm, tôi tự hỏi những gì hệ điều hành được bỏ ra khỏi danh sách này ...?) - sendmsg của tất nhiên có thể làm điều đó (trên một "ổ cắm Unix", bằng cách sử dụng cờ SCM_RIGHTS).

Giờ đây, người nghèo có giá trị multiprocessing hoàn toàn đúng để không khai thác tính năng này (thậm chí giả sử có thể có ma thuật đen để triển khai nó trên Windows) - hầu hết các nhà phát triển sẽ không nghi ngờ gì nữa mở tập tin đồng thời và chạy vào điều kiện chủng tộc). Cách thích hợp duy nhất để sử dụng nó là cho một quy trình có độc quyền mở một số tệp nhất định để chuyển các tệp đã mở tới một quy trình khác chạy với các đặc quyền giảm - và sau đó không bao giờ sử dụng lại xử lý đó nữa. Không có cách nào để thực thi điều đó trong mô-đun multiprocessing.

Quay lại câu hỏi gốc của @ Andy, trừ khi anh ấy chỉ làm việc trên Linux (và chỉ với quy trình cục bộ) và sẵn sàng chơi các thủ thuật bẩn với hệ thống tệp/proc, anh ấy sẽ phải xác định cấp ứng dụng của mình cần mạnh hơn và tuần tự hóa file các đối tượng phù hợp. Hầu hết các tệp đều có một đường dẫn (hoặc có thể được tạo để có: một tệp ít đường dẫn là khá hiếm, thực sự không tồn tại trên Windows mà tôi tin) và do đó có thể được tuần tự hóa qua nó - nhiều tệp khác đủ nhỏ để tuần tự hóa bằng cách gửi nội dung trên - vv, v.v.

+0

Tôi nghĩ điều tôi muốn nói (làm cho điều này ít nhất là lần sửa thứ hai) là tệp * bộ mô tả * - nơi bạn thường nhận được một số> = 3 (do 0,1, 2 được dành riêng cho std {in, out, err}). Vì vậy, nếu bạn mở một tập tin và nó mô tả là 3, đi qua 3 đến một quá trình khác là vô nghĩa. Cuối cùng tôi đã đánh nó ở đó phải không? –

+0

cảm ơn rất nhiều, Alex! Vì vậy, như bạn đã nói, nó là rất khó khăn nếu tôi muốn vượt qua xử lý tập tin giữa các quá trình trên cửa sổ. Nếu tôi muốn vượt qua các tập tin, tôi nên vượt qua đường dẫn tập tin hoặc nội dung của tập tin, không phải tập tin xử lý. – Ryan

+0

@Mark, không thực sự, nó thực sự là '3' bạn cần phải vượt qua ... chỉ trên một ổ cắm AF_UNIX và với cờ SCM_RIGHTS (hạt nhân sẽ làm phần còn lại của ma thuật cần thiết: số lượng có thể đến! = 3 nhưng nó sẽ là một bộ mô tả cho cùng một tệp mở). Solaris có một cách sạch hơn, nếu tôi nhớ chính xác, và thực sự một số syscalls để đối phó đúng với vấn đề (nhưng nó đã quá lâu kể từ khi tôi thực sự làm việc trên Solaris, thở dài, tôi không nhớ lại). –

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