Я работаю с сокетами, используя Python 3.5 и модуль multiprocessing
, и столкнулся с неожиданным поведением.Моя программа, по сути, состоит из пары потоков, которые выполняются до тех пор, пока клиент не получит определенное сообщение с указанием остановить его.
Если я выполню его таким образом, я получу BrokenPipeError
, который прерывает программу, несмотря на *Цикл 1005 * и блок except
.
#!/usr/bin/env python3
import signal
import traceback
from multiprocessing.dummy import Pool
from process import Process
def main():
while True:
try:
# a Process has a couple threads
process = Process()
listener_pool = Pool(processes=1)
sender_pool = Pool(processes=1)
# blocking socket client that runs forever
listener_pool.apply_async(process.listener_thread.run, ())
# blocking socket server that runs forever
sender_pool.apply_async(process.sender_thread.run, ())
return 0
except BrokenPipeError:
traceback.print_exc()
# closing connections
process.emitter_thread.socket.close()
process.listener_thread.socket.close()
if __name__ == '__main__':
main()
Однако, когда я добавил signal.pause()
прямо перед возвратом, не только код работает, как задумано, но также не вызывается BrokenPipeError
в любомвремя.
#!/usr/bin/env python3
import signal
import traceback
from multiprocessing.dummy import Pool
from process import Process
def main():
while True:
try:
# a Process has a couple threads
process = Process()
listener_pool = Pool(processes=1)
sender_pool = Pool(processes=1)
# blocking socket client that runs forever
listener_pool.apply_async(process.listener_thread.run, ())
# blocking socket server that runs forever
sender_pool.apply_async(process.sender_thread.run, ())
signal.pause()
return 0
except BrokenPipeError:
traceback.print_exc()
# closing connections
process.emitter_thread.socket.close()
process.listener_thread.socket.close()
if __name__ == '__main__':
main()
В соответствии с документами сигналы могут обрабатываться только основным потоком, но оба сокета обрабатываются вторичными потоками.Что делает signal.pause()
, чтобы предотвратить разрыв сокетов, когда они даже не вызываются в одном и том же контексте?