Как выйти из процесса Python, если какой-либо параллельный поток завершается?

#python #multithreading

#python #многопоточность

Вопрос:

У меня есть процесс python с основным потоком, запускающим параллельные потоки для 1 gRPC-сервера и 1 HTTP-сервера. Я хочу, чтобы процесс ОС для этого приложения завершался, если КАКОЙ-либо из параллельных потоков завершается.

Я думаю, что основной поток, как здесь закодировано, будет ждать до тех пор, пока будет запущен один параллельный поток. Что мне нужно сделать, чтобы изменить это, чтобы основной поток завершался, как только завершается любой параллельный поток?

 if __name__ == '__main__':
  svc = MyService()
  t1 = GrpcServer(svc)
  t1.start()
  t2 = HealthHttpServer()
  t2.start()
  

с серверами, определенными как

 class GrpcServer(threading.Thread):
  def __init__(self, service):
    super().__init__()
    self.grpcServer(futures.ThreadPoolExecutor(max_workers=10))
    self.grpcServer.add_insecure_port('[::]:8000')
    myservice_pb2_grpc.add_MyServiceServicer_to_server(service, self.grpcServer)

  def run(self):
    self.grpcserver.start()

class HealthServer(Thread):
    def __init__(self):
        super().__init__()

    def run(self):
        port=2113
        httpd = HTTPServer(('localhost', port), HealthHTTPRequestHandler)
        httpd.serve_forever()

class HealthHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        '''Respond to a GET request.'''
        if self.path == '/healthz':
            self.send_response(HTTPStatus.OK)
            self.end_headers()
            self.wfile.write(b'ok')
        else:
            self.send_response(HTTPStatus.NOT_FOUND)
            self.end_headers()
  

Комментарии:

1. Вызовите API TerminateProcess() вашей ОС?

Ответ №1:

Самое чистое, что я нашел до сих пор, это:

  • определите все эти потоки как потоки демона
  • определите глобальную потоковую обработку.Объект события
  • добавьте попытку верхнего уровня … finally в каждый поток и вызовите это событие ‘ set() в finally
  • в основном потоке ожидайте этого события после запуска потоков

Если что-то пойдет не так в любом из потоков, будет выполнен блок finally, сигнализирующий об этом событии и разблокирующий основной поток, который завершается. Все остальные потоки, являющиеся потоками демона, завершат процесс.