Подтвердить что ты не робот

Почему 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.

4b9b3361

Ответ 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()