2009-07-02 19 views
5

मेरे पास प्रक्रियाओं के बीच फ़ाइल हैंडल के साथ साझा संसाधन के बारे में कोई प्रश्न है। यहाँ अपने परीक्षण कोड है:प्रक्रियाओं के बीच फ़ाइल हैंडल विशेषता के साथ ऑब्जेक्ट्स साझा करें

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() 

तब मैं प्राप्त एक KeyError नीचे की तरह:

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' 

मुझे लगता है कि जब मैं कतार में File() वस्तु डाल, वस्तु धारावाहिक हो गया, और फ़ाइल हैंडल नहीं कर सकता serialized हो, तो, मुझे KeyError मिला:

किसी को भी इसके बारे में कोई विचार है? अगर मैं फाइल हैंडल विशेषता के साथ वस्तुओं को साझा करना चाहता हूं, तो मुझे क्या करना चाहिए?

उत्तर

7

मुझे ऑब्जेक्ट करना है (लंबाई में, केवल एक टिप्पणी में फिट नहीं होगा ;-) @ मार्क के बार-बार दावा करने के लिए कि फाइल हैंडल को "चल रही प्रक्रियाओं के बीच पारित नहीं किया जा सकता" - यह सच नहीं है असली, आधुनिक ऑपरेटिंग सिस्टम, जैसे ओह, कहते हैं, यूनिक्स (मुफ्त बीएसडी वेरिएंट्स, मैकोज़क्स, और लिनक्स, शामिल हैं - हमम, मुझे आश्चर्य है कि ओएस को इस सूची से क्या छोड़ा गया है ...? -) - sendmsg पाठ्यक्रम SCM_RIGHTS ध्वज का उपयोग करके (यूनिक्स सॉकेट "पर) कर सकता है।

अब गरीब, मूल्यवान multiprocessing पूरी तरह से सही करने के लिए (यहां तक ​​कि विंडोज पर इसे लागू करने के भी काला जादू हो सकता है यह सोचते हैं) इस सुविधा का फायदा उठाने नहीं है - सबसे डेवलपर्स कोई संदेह नहीं है यह वैसे भी दुरुपयोग होता है (होने कई प्रक्रियाओं एक ही का उपयोग एक साथ खुली फ़ाइल और दौड़ की स्थिति में चल रहा है)। इसका उपयोग करने का एकमात्र उचित तरीका एक ऐसी प्रक्रिया के लिए है जिसमें खोले गए फाइलों को दूसरी प्रक्रिया में पास करने के लिए कुछ फाइलें खोलने के अनन्य अधिकार हैं जो कम विशेषाधिकारों के साथ चलते हैं - और तब कभी भी उस संभाल को कभी भी उपयोग न करें। multiprocessing मॉड्यूल में, वैसे भी लागू करने का कोई तरीका नहीं है।

@ एंडी के मूल प्रश्न पर वापस जाएं, जब तक कि वह केवल लिनक्स पर काम नहीं करेगा (और केवल स्थानीय प्रक्रियाओं के साथ) और/proc फाइल सिस्टम के साथ गंदे चाल खेलने के इच्छुक हैं, उन्हें अपने आवेदन-स्तर को परिभाषित करना होगा तदनुसार file वस्तुओं को और अधिक तेज़ी से और क्रमबद्ध करने की आवश्यकता है। अधिकांश फ़ाइलों में एक पथ होता है (या इसे रखने के लिए बनाया जा सकता है: पथ-रहित फ़ाइलें बहुत दुर्लभ हैं, वास्तव में विंडोज़ पर विश्वास नहीं है) और इस प्रकार इसके माध्यम से क्रमबद्ध किया जा सकता है - कई अन्य उनके द्वारा भेजकर क्रमबद्ध करने के लिए पर्याप्त छोटे हैं सामग्री आदि - आदि,

+0

मुझे लगता है कि मुझे क्या कहना है (कम से कम दूसरा सुधार करना) फाइल * डिस्क्रिप्टर * था - जहां आपको आम तौर पर एक संख्या मिलती है> = 3 (0,1 के कारण, 2 std {in, out, err} के लिए आरक्षित किया जा रहा है)। तो यदि आप एक फ़ाइल खोलते हैं और यह वर्णनकर्ता 3 है, तो दूसरी प्रक्रिया में 3 पास करना व्यर्थ है। क्या मैंने अंततः वहां मारा? –

+0

बहुत धन्यवाद, एलेक्स! इसलिए, जैसा कि आपने कहा था, अगर मैं विंडोज़ पर प्रक्रियाओं के बीच फाइल हैंडल पास करना चाहता हूं तो यह बहुत मुश्किल है। अगर मैं फाइल पास करना चाहता हूं, तो मुझे फ़ाइल पथ या फ़ाइल की सामग्री को पास करना चाहिए, फ़ाइल हैंडल नहीं। – Ryan

+0

@ मार्क, वास्तव में नहीं, यह वास्तव में '3' है जिसे आपको पास करने की आवश्यकता है ... केवल एक AF_UNIX सॉकेट पर और SCM_RIGHTS ध्वज के साथ (कर्नेल शेष आवश्यक जादू करेगा: संभवतः आने वाली संख्या हो सकती है! = 3 लेकिन यह एक ही खुली फ़ाइल के लिए एक वर्णक होगा)। सोलारिस के पास एक क्लीनर तरीका है, अगर मुझे सही तरीके से याद किया जाता है, और वास्तव में इस मुद्दे के साथ ठीक से निपटने के लिए कई सिस्को (लेकिन यह बहुत लंबा रहा है क्योंकि मैंने वास्तव में सोलारिस पर काम किया था, मुझे लगता है कि मुझे तेजी से याद नहीं है)। –

संबंधित मुद्दे