Почему pipe_close() не вызывает EOFError во время pipe.recv() в многопроцессорной обработке python?
Я посылаю простые объекты между процессами, используя каналы с модулем многопроцессорности Python. В документации указано, что если труба была закрыта, вызов pipe.recv() должен поднять EOFError. Вместо этого моя программа просто блокирует recv() и никогда не обнаруживает, что канал закрыт.
Пример:
import multiprocessing as m
def fn(pipe):
print "recv:", pipe.recv()
print "recv:", pipe.recv()
if __name__ == '__main__':
p1, p2 = m.Pipe()
pr = m.Process(target=fn, args=(p2,))
pr.start()
p1.send(1)
p1.close() ## should generate EOFError in remote process
И результат выглядит следующим образом:
recv: 1
<blocks here>
Может ли кто-нибудь сказать мне, что я делаю неправильно? У меня есть эта проблема для Linux и windows/cygwin, но not для Windows Python.
Ответы
Ответ 1
Обработанный (дочерний) процесс наследует копию его родительских файловых дескрипторов. Поэтому, даже если родительский вызов "закрывается" на p1
, у ребенка все еще есть открытая копия, и основной объект ядра не освобождается.
Чтобы исправить, вам нужно закрыть сторону записи в канале в дочернем элементе, например:
def fn(pipe):
p1.close()
print "recv:", pipe.recv()
print "recv:", pipe.recv()
Ответ 2
Из это решение. Я заметил, что os.close(pipe.fileno())
может немедленно разорвать трубу, где pipe.close() не работает, пока не закончится все процессы/подпроцессы, Вы могли бы попробовать это вместо этого.
Предупреждение: вы не можете использовать pipe.close() после, но pipe.closed stills возвращают "false". Таким образом, вы можете сделать это, чтобы быть чище:
os.close(pipe.fileno())
pipe=open('/dev/null')
pipe.close()