我有一个gRPC
服务器,它使用ProcessPoolExecutor
和max_workers=1
来运行脚本Here就是为什么我必须在run_brain_application
和max_workers=1
中使用ProcessPoolExecutor。下面是服务器脚本的简化版本
我放置了两个print语句来打印process
的开头和结尾
问题是,对于某些请求,流程有时会启动,但从未完成。我的意思是它打印START
,但我从来没有看到STOP
。同一个请求在下一次起作用,因此问题不在于请求。此外,如果run_application
中存在异常,则会在没有任何问题的情况下抛出该异常
我已经检查了有关Stackoverflow的所有相关问题,但其中大多数(1,2)都是关于他们的进程没有抛出异常,这不是我的情况
任何想法都非常感谢
谢谢
class BrainServer(brain_pb2_grpc.BrainServiceServicer):
def run_brain_application(self, request, context):
request_dict = MessageToDict(
request,
preserving_proto_field_name=True,
keep_null=True
)
print("START")
with futures.ProcessPoolExecutor(max_workers=1) as executor:
result = executor.submit(run_application, request_dict).result()
res = result.get('data')
print("STOP")
report = dict_to_protobuf(result_pb2.Result, {res_type: res}, strict=False)
return report
except Exception as e:
_log_fatal(
msg=str(e)
)
raise e
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=16))
brain_pb2_grpc.add_BrainServiceServicer_to_server(BrainServer(), server)
server.add_insecure_port(f"[::]:{GRPC_PORT}")
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
这是一个很难确定的问题
我首先建议给你的遗嘱执行人增加超时时间
我还建议只使用
ThreadPoolExecutor
,看看问题是否得到解决。pythonlogger
和其他一些组件在多进程环境中使用时表现不佳See。我的猜测是,您使用的python资源不应该在进程之间共享,但它们确实是(我的直接怀疑是logger
)当父进程是多线程的时,使用
os.fork
创建子进程是有问题的。concurrent.futures.ProcessPoolExecutor
内部使用的multiprocesing
模块提供了多种创建子进程的方法。这些方法称为start方法,它们被命名为fork、spawn和forkserver建议多线程父级使用forkserver方法创建子级,因为在forkserver方法中,创建的服务器是单线程的,多线程父级请求服务器创建子级。由于服务器是单线程的
os.fork
,因此没有问题concurrent.futures.ProcessPoolExecutor
接受mp_context
参数,它使用该参数设置池中进程的启动方法。所以你应该通过
mp_context
Contexts and start methods
相关问题 更多 >
编程相关推荐