zeromq和python多处理,打开的文件太多

zeromq和python多处理,打开的文件太多,zeromq,python-multiprocessing,Zeromq,Python Multiprocessing,我有一个基于代理的模型,其中几个代理由一个中心进程启动,并通过另一个中心进程进行通信。每个代理和通信过程都通过zmq进行通信。但是,当我启动100多个代理时,standard_发出: 无效参数(src/stream_engine.cpp:143)打开的文件太多 (src/ipc_listener.cpp:292) Mac Os会提示问题报告: Python在使用libzmq.5.dylib插件时意外退出 在我看来,问题是打开的上下文太多了。但是,我如何通过多处理避免这种情况呢 我附上以下部分代码

我有一个基于代理的模型,其中几个代理由一个中心进程启动,并通过另一个中心进程进行通信。每个代理和通信过程都通过zmq进行通信。但是,当我启动100多个代理时,standard_发出:

无效参数(src/stream_engine.cpp:143)打开的文件太多 (src/ipc_listener.cpp:292)

Mac Os会提示问题报告:

Python在使用libzmq.5.dylib插件时意外退出

在我看来,问题是打开的上下文太多了。但是,我如何通过多处理避免这种情况呢

我附上以下部分代码:

类代理(数据库、记录器、交易、消息传递、多处理.Process):
定义初始化(自我、idn、组、地址、交易日志):
多处理。进程。初始化(自)
....
def运行(自):
self.context=zmq.context()
self.commands=self.context.socket(zmq.SUB)
self.commands.connect(self.\u地址['command\u address'])
self.commands.setsockopt(zmq.SUBSCRIBE,“all”)
self.commands.setsockopt(zmq.SUBSCRIBE,self.name)
self.commands.setsockopt(zmq.SUBSCRIBE,group_地址(self.group))
self.out=self.context.socket(zmq.PUSH)
self.out.connect(self.\u地址['frontend'])
睡眠时间(0.1)
self.database_connection=self.context.socket(zmq.PUSH)
self.database\u connection.connect(self.\u地址['database'])
睡眠时间(0.1)
self.logger_connection=self.context.socket(zmq.PUSH)
self.logger\u connection.connect(self.\u地址['logger']))
self.messages_in=self.context.socket(zmq.DEALER)
self.messages_in.setsockopt(zmq.IDENTITY,self.name)
self.messages_in.connect(self._地址['backend']))
self.shout=self.context.socket(zmq.SUB)
self.shout.connect(self.\u地址['group\u backend'])
self.shout.setsockopt(zmq.SUBSCRIBE,“all”)
self.shout.setsockopt(zmq.SUBSCRIBE,self.name)
self.shout.setsockopt(zmq.SUBSCRIBE,组地址(self.group))
self.out.send_multipart(['!','!','register_agent',self.name])
尽管如此:
尝试:
self.commands.recv()捕获组地址。
除键盘中断外:
print('KeyboardInterrupt:%s,self.commands.recv()捕获自己的地址~1888'(self.name))
打破
command=self.commands.recv()
如果命令==“!”:
子命令=self.commands.recv()
如果子命令=='die':
自身信号完成()
打破
尝试:
self.\u方法[命令]()
除KeyError外:
如果命令不在self.\u方法中:
raise SystemExit('agent_列表中调用的方法-'+command+')未声明('+self.name)
其他:
提升
除键盘中断外:
打印('KeyboardInterrupt:%s,当前命令:%s~1984'(self.name,command))
打破
如果命令[0]!='\':
self.\u拒绝接受调查但不接受报价()
自身信号完成()
#self.context.destroy()

整个代码可能不是太多上下文,而是太多套接字。查看您的repo,我发现您(正确地)使用IPC作为传输;IPC使用文件描述符作为“地址”在不同进程之间来回传递数据。如果我读得正确,则每个进程都会打开到7个套接字,这样会很快增加。我打赌,如果在代码中间进行一些调试,则会看到在创建最后一个上下文时它不会失败,但当最后一个套接字推送打开文件限制时,它不会失败。边缘


我的理解是,开放式FD的典型用户限制约为1000,因此,在大约100个代理中,您仅为套接字推送700个开放式FD。其余部分可能只是典型的。将限制增加到10000,并根据您的情况提高上限,应该没有问题。否则,您必须重写以使用更少的套接字每个进程获得更高的进程限制。

这与zeromq或python无关。它是底层操作系统,只允许高达某个阈值的并发打开文件。此限制包括正常文件,但也包括套接字连接

您可以使用
ulimit-n
查看当前限制,它可能默认为
1024
。运行服务器或有其他原因(如您的多处理)的计算机通常需要将此限制设置得更高或仅设置为
unlimited

此外,还有另外一个问题,不过我还没有什么需要调整的


一般来说,你应该问问自己,如果你真的需要那么多代理。通常,
X
/
2X
工作进程就足够了,其中
X
对应于你的CPU计数。

。这是一个很好的观点,你应该明确地评估你是否真的需要并且能够有效地利用你正在旋转的尽可能多的代理.