TłoOSError: [Errno 11] Zasoby czasowo niedostępne. Co to powoduje?
Mam dwa procesy Pythona, które muszą komunikować się ze sobą. Kombinacja jest obsługiwana przez klasę o nazwie Pipe. Zrobiłem dla tego oddzielną klasę, ponieważ większość informacji, które muszą zostać przekazane, ma postać słowników, więc Pipe implementuje do tego prosty protokół.
Oto konstruktor rury:
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)
Więc najlepiej byłoby po prostu zbudować rurę w każdym procesie z tej samej ścieżce i byliby w stanie mówić miłe.
Będę pomijać rzeczy o protokole, ponieważ myślę, że to w dużej mierze niepotrzebne tutaj.
Wszystkie operacje odczytu i zapisu skorzystać z następujących funkcji „bazy”:
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 został zaproponowany w innym poście
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
blokowania i odblokowywania jest obsługiwany tak:
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')
Problem
Ten czasami dzieje:
....in base_read
lBytes = os.read(self.iFH,iLen)
OSError: [Errno 11] Resource temporarily unavailable
Czasami jest dobrze.
Magiczny Rozwiązanie
I wydaje się, że zatrzymał się problem z dzieje. Proszę zauważyć, że to nie ja odpowiadam na własne pytanie. Moje pytanie wyjaśniono w następnej sekcji.
zmieniłem odczytu funkcje wyglądają bardziej jak to i sortowane rzeczy się:
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
Pytanie
Ja usiłuje dowiedzieć się dokładnie, dlaczego jest chwilowo niedostępny. Te dwa procesy nie mogą uzyskać dostępu do aktualnie nazwanej potoku w tym samym czasie z powodu mechanizmu blokującego (chyba że się mylę?), Tak jest z powodu czegoś bardziej fundamentalnego dla fifos, którego mój program nie bierze pod uwagę?
Wszystko, czego naprawdę chcę, to wyjaśnienie ... Rozwiązanie, które znalazłem działa, ale wygląda na magię. Czy ktoś może zaoferować wyjaśnienie?
systemu
- Ubuntu 12.04,
- Python3.2.3
Chodzi o to, aby utworzyć wiele potoków. Tak więc proces A tworzy rurę, a proces B tworzy rurę o tej samej ścieżce. Następnie proces A może powiedzieć 'pipe.write (some_dictionary)', a proces B może powiedzieć 'some_dictionary = pipe.read()' – Sheena
również, jeśli problem był liczbą uruchomionych rzeczy, wtedy wywołanie sleep() nie Naprawiać rzeczy. Chyba że czegoś brakuje ... – Sheena