Python: дождитесь завершения дочернего процесса ИЛИ нового подключения

Мне нужно реализовать что-то вроде этого:

while True:
    conn,addr = socket.accept()
    restore()
    p.kill()

    #...
    p = subprocess.Popen(...)

Но мне нужно, чтобы функция restore() вызывалась не только после каждого нового соединения, но и как только p умирает.

Я могу «заблокировать» свою программу, ожидающую смерти p, выполнив p.wait(), однако в то же время я хочу заблокировать свою программу, ожидающую нового соединения.

Другими словами, мне нужно заблокировать мою программу до тех пор, пока не будет выполнено одно из этих двух условий: «p умирает» ИЛИ «новое соединение».

Я знаю, что могу использовать select для ожидания двух файловых дескрипторов, но я не знаю, как поступить в этом случае.

Спасибо


person user975176    schedule 13.09.2015    source источник
comment
Используйте gevent (gevent.org), и ваш код с p.wait() будет работать так, как вы хотите.   -  person mguijarr    schedule 13.09.2015
comment
вы можете использовать signal.set_wakeup_fd() для интеграции p.wait() в цикл select(). Вероятно, вы могли бы использовать asyncio/twisted/gevent вместо того, чтобы самостоятельно переопределять функциональность.   -  person jfs    schedule 13.09.2015


Ответы (1)


Это решение, которое я использовал:

def wait_socket_and_process(s,process):
    while True:
        rr,_,_ = select.select([s],[],[],0.1)
        if len(rr)>0:
            conn, addr = rr[0].accept()
            process.kill()
            process.poll()
            #handle process termination
            print "* subprocess killed"
            return conn, addr

        elif (process.poll() != None):
            #handle process termination
            print "* subprocess terminated"


s = socket.#...
process = subprocess.Popen(...)
wait_socket_and_process(s,process)
#handle new connection...

Как предполагают другие, могут быть более чистые/более общие способы сделать это с использованием таких библиотек, как getenv.

person user975176    schedule 18.09.2015