我有一个使用 64 位 Python 3.3.0 CPython 解释器在 64 位 Linux(内核版本 2.6.28.4)机器上运行的自定义模拟器(用于生物学)。
因为模拟器依赖于许多独立实验以获得有效结果,所以我内置了并行处理来运行实验。线程之间的通信主要发生在使用托管
multiprocessing Queue
s ( doc ) 的生产者-消费者模式下。该架构的概要如下:
- 处理生成和管理
Process
es 和各种Queue
s的主进程 - N 个进行模拟的工作进程
- 1 个结果消费者进程,消耗模拟结果并对结果进行排序和分析
主进程和工作进程通过输入进行通信Queue
。类似地,工作进程将他们的结果放在一个输出Queue
中,结果消费者进程从中消费项目。最终的 ResultConsumer 对象通过multiprocessing Pipe
( doc ) 传递回主进程。
一切正常,直到它尝试通过以下方式将 ResultConsumer 对象传递回主进程Pipe
:
Traceback (most recent call last):
File "/home/cmccorma/.local/lib/python3.3/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/home/cmccorma/.local/lib/python3.3/multiprocessing/process.py", line 95, in run
self._target(*self._args, **self._kwargs)
File "DomainArchitectureGenerator.py", line 93, in ResultsConsumerHandler
pipeConn.send(resCon)
File "/home/cmccorma/.local/lib/python3.3/multiprocessing/connection.py", line 207, in send
self._send_bytes(buf.getbuffer())
File "/home/cmccorma/.local/lib/python3.3/multiprocessing/connection.py", line 394, in _send_bytes
self._send(struct.pack("!i", n))
struct.error: 'i' format requires -2147483648 <= number <= 2147483647
我了解前两个跟踪(库中未处理的退出Process
),第三个是我用于将 ResultConsumer 对象发送
Pipe
到主进程的代码行。最后两条痕迹是有趣的地方。A Pipe
pickle 发送给它的任何对象,并将生成的字节传递到另一端(匹配连接),在运行时它被 unpickle recv()
。 self._send_bytes(buf.getbuffer())
正在尝试发送腌制对象的字节。 self._send(struct.pack("!i", n))
正在尝试使用长度为 n 的整数(网络/大端序)打包结构,其中 n 是作为参数传入的缓冲区的长度(该struct
库处理 Python 值和表示为 Python 字符串的 C 结构之间的转换,请参阅文档)。
此错误仅在尝试大量实验时发生,例如 10 次实验不会导致它,但 1000 会始终如一(所有其他参数保持不变)。到目前为止,我最好的假设struct.error
是,试图向下推送管道的字节数超过 2^32-1 (2147483647) 或 ~2 GB。
所以我的问题有两个:
我的调查陷入困境,因为
struct.py
基本上只是从进口_struct
,我不知道那在哪里。考虑到底层架构都是 64 位的,字节限制似乎是任意的。那么,为什么我不能通过比这更大的东西呢?此外,如果我不能改变这一点,这个问题有什么好的(阅读:简单的)解决方法吗?
注意:我认为使用 aQueue
代替 aPipe
不能解决问题,因为我怀疑Queue
使用了类似的酸洗中间步骤。 编辑:正如 abarnert 的回答中指出的那样,这个注释是完全不正确的。