SfondoOSError: [Errno 11] Risorsa temporaneamente non disponibile. Che cosa causa questo?
Ho due processi Python che devono comunicare tra loro. La permutazione è gestita da una classe chiamata Pipe. Ho creato una classe separata per questo perché la maggior parte delle informazioni che devono essere comunicate si presenta sotto forma di dizionari, quindi Pipe implementa un protocollo piuttosto semplice per farlo.
Ecco il costruttore del tubo:
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)
Quindi idealmente vorrei solo costruire un tubo in ogni processo con lo stesso percorso e sarebbero in grado di parlare bello.
Ho intenzione di saltare le cose sul protocollo perché penso che sia in gran parte inutile qui.
Tutte le operazioni di lettura e scrittura fanno uso delle seguenti funzioni 'base':
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 stato suggerito in un altro post
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
bloccaggio e lo sbloccaggio viene gestito in questo modo:
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')
Il problema
Questo volte accade:
....in base_read
lBytes = os.read(self.iFH,iLen)
OSError: [Errno 11] Resource temporarily unavailable
A volte va bene.
La soluzione magica
mi sembra di aver fermato il problema si verifichi. Si prega di notare che non sono io che rispondo alla mia stessa domanda. La mia domanda è spiegata nella prossima sezione.
ho cambiato il funzioni di lettura a guardare più come questo e risolto roba:
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
La questione
sto lottando per scoprire esattamente il motivo per cui è temporaneamente non disponibile. I due processi non possono accedere contemporaneamente alla pipe denominata effettiva a causa del meccanismo di blocco (a meno che non mi sbaglio?), Quindi questo è dovuto a qualcosa di più fondamentale di fifos che il mio programma non sta prendendo in considerazione?
Tutto ciò che voglio veramente è una spiegazione ... La soluzione che ho trovato funziona ma sembra magica. Qualcuno può offrire una spiegazione?
sistema
- Ubuntu 12.04,
- Python3.2.3
Il punto è creare più pipe. Quindi il processo A crea un tubo e il processo B crea un tubo con lo stesso percorso. Quindi il processo A può dire 'pipe.write (some_dictionary)' e il processo B può dire 'some_dictionary = pipe.read()' – Sheena
Inoltre, se il problema era il numero di cose in esecuzione, allora mettere una chiamata in sleep() non sarebbe Sistemare cose. A meno che non manchi qualcosa ... – Sheena