2012-11-12 32 views
7

पृष्ठभूमिOSError: [Errno 11] संसाधन अस्थायी रूप से अनुपलब्ध है। इसका क्या कारण है?

मैं दो अजगर प्रक्रियाओं को एक दूसरे के साथ संवाद करने की आवश्यकता है। प्रसंस्करण पाइप नाम की एक कक्षा द्वारा संभाला जाता है। मैंने इसके लिए एक अलग वर्ग बनाया क्योंकि अधिकांश जानकारी जिन्हें संचारित करने की आवश्यकता है, शब्दकोशों के रूप में आता है ताकि पाइप ऐसा करने के लिए एक बहुत ही सरल प्रोटोकॉल लागू कर सके।

def __init__(self,sPath): 
    """ 
    create the fifo. if it already exists just associate with it 
    """ 
    self.sPath = sPath 
    if not os.path.exists(sPath): 
     try: 
      os.mkfifo(sPath) 
     except: 
      raise Exception('cannot mkfifo at path \n {0}'.format(sPath)) 
    self.iFH = os.open(sPath,os.O_RDWR | os.O_NONBLOCK) 
    self.iFHBlocking = os.open(sPath,os.O_RDWR) 

तो आदर्श मैं सिर्फ एक पाइप प्रत्येक प्रक्रिया में एक ही पथ के साथ बनाएगी और वे अच्छा में बात करने में सक्षम हो जाएगा:

यहाँ पाइप निर्माता है।

मैं प्रोटोकॉल के बारे में सामान छोड़ने जा रहा हूं क्योंकि मुझे लगता है कि यह काफी हद तक अनावश्यक है।

:

def base_read_blocking(self,iLen): 
    self.lock() 
    lBytes = os.read(self.iFHBlocking,iLen) 
    self.unlock() 
    return lBytes 

def base_read(self,iLen): 
    print('entering base read') 
    self.lock() 
    lBytes = os.read(self.iFH,iLen) 
    self.unlock() 
    print('exiting base read') 
    return lBytes 

def base_write_blocking(self,lBytes): 
    self.lock() 
    safe_write(self.iFHBlocking,lBytes) 
    self.unlock() 

def base_write(self,lBytes): 
    print('entering base write') 
    self.lock() 
    safe_write(self.iFH,lBytes) 
    self.unlock() 
    print('exiting base write') 

safe_write एक और पोस्ट

def safe_write(*args, **kwargs): 
    while True: 
     try: 
      return os.write(*args, **kwargs) 
     except OSError as e: 
      if e.errno == 35: 
       import time 
       print(".") 
       time.sleep(0.5) 
      else: 
       raise 

लॉक और अनलॉक इस तरह नियंत्रित किया जाता है में सुझाव दिया गया था:

सभी पढ़ने और लिखने के संचालन निम्नलिखित 'आधार' कार्यों का इस्तेमाल करते हैं

def lock(self): 
    print('locking...') 
    while True: 
     try: 
      os.mkdir(self.get_lock_dir()) 
      print('...locked') 
      return 
     except OSError as e: 
      if e.errno != 17: 
       raise e 

def unlock(self): 
    try: 
     os.rmdir(self.get_lock_dir()) 
    except OSError as e: 
     if e.errno != 2: 
      raise e 
    print('unlocked') 

समस्या

यह कभी कभी होता है:

....in base_read 
lBytes = os.read(self.iFH,iLen) 
OSError: [Errno 11] Resource temporarily unavailable 

कभी कभी यह ठीक है।

जादुई समाधान

मैं ऐसा होने से समस्या बंद कर दिया है लगता है। कृपया ध्यान दें कि यह मेरे अपने प्रश्न का उत्तर नहीं दे रहा है। मेरा प्रश्न अगले खंड में समझाया गया है।

def base_read(self,iLen): 
    while not self.ready_for_reading(): 
     import time 
     print('.') 
     time.sleep(0.5) 

    lBytes = ''.encode('utf-8') 
    while len(lBytes)<iLen: 
     self.lock() 
     try: 
      lBytes += os.read(self.iFH,iLen) 
     except OSError as e: 
      if e.errno == 11: 
       import time 
       print('.') 
       time.sleep(0.5) 
     finally: 
      self.unlock() 
     return lBytes 


def ready_for_reading(self): 
    lR,lW,lX = select.select([self.iFH,],[],[],self.iTimeout) 
    if not lR: 
     return False 
    lR,lW,lX = select.select([self.iFHBlocking],[],[],self.iTimeout) 
    if not lR: 
     return False 
    return True 

प्रश्न मैं पता लगाने के लिए वास्तव में क्यों यह अस्थायी रूप से अनुपलब्ध है संघर्ष कर रहा हूँ:

मैं पढ़ने के कार्यों बदल अधिक इस तरह देखने के लिए और यह सामान हल। लॉकिंग तंत्र के कारण दोनों प्रक्रियाएं एक ही समय में वास्तविक नामित पाइप तक नहीं पहुंच सकती हैं (जब तक कि मुझे गलत नहीं लगता?) तो क्या यह फीफो के लिए कुछ और मौलिक कारण है कि मेरा प्रोग्राम ध्यान में नहीं ले रहा है?

मैं वास्तव में एक स्पष्टीकरण चाहता हूं ... जो समाधान मैंने पाया वह काम करता है लेकिन यह जादू की तरह दिखता है। क्या कोई स्पष्टीकरण दे सकता है?

सिस्टम

  • Ubuntu 12.04,
  • Python3.2।3

उत्तर

3

मैं पहले एक similar problem with Java था। स्वीकार्य उत्तर पर एक नज़र डालें --- समस्या यह थी कि मैं एक लूप में नए धागे बना रहा था। मेरा सुझाव है कि आपको पाइप बनाने वाले कोड पर एक नज़र डालें और सुनिश्चित करें कि आप एकाधिक पाइप नहीं बना रहे हैं।

+1

बिंदु एकाधिक पाइप्स बनाना है। तो प्रक्रिया ए एक पाइप बनाता है और प्रक्रिया बी एक ही पथ के साथ एक पाइप बनाता है। फिर प्रक्रिया ए कह सकता है 'pipe.write (some_dictionary)' और प्रक्रिया बी 'some_dictionary = pipe.read() ' – Sheena

+0

भी कह सकती है, अगर समस्या चल रही चीजों की संख्या थी तो नींद डालने() कॉल नहीं होगी चीजों को ठीक करें। जब तक मैं कुछ याद नहीं कर रहा हूँ ... – Sheena