Python实现Lmax使用多进程运行报AttributeError无法获取属性问题
报错原因
- Windows系统下Python多进程默认使用
spawn启动模式,子进程启动时会重新导入整个主脚本模块。你将unmarshallerReader、consumeReader等所有工作函数都定义在了if __name__ == '__main__'代码块内部,子进程导入模块时不会执行if __name__ == '__main__'内的代码,因此找不到这些函数定义,序列化(pickle)过程就抛出了属性不存在的错误。 - 额外隐藏问题:你定义的
cb环形缓冲区实例也在if __name__ == '__main__'内部,普通类实例默认无法跨进程共享,子进程拿到的只是该实例的拷贝,多个进程操作的不是同一个缓冲区,就算函数问题修复后也无法正常实现Lmax逻辑。同时原代码重复启动了两次p1进程,属于冗余逻辑。
修复方案
- 将所有工作函数移到
if __name__ == '__main__'外部,保证子进程导入模块时可以访问到这些函数。 - 如果使用的
disruptor.CircularBuffer不支持跨进程共享,需要替换为Python多进程原生支持的共享数据结构(比如multiprocessing.Queue),或者将环形缓冲区改造为支持共享内存的实现,保证所有进程操作同一份缓冲区数据。
修复后示例代码
import disruptor import multiprocessing import random # 工作函数全部移到if __name__ == '__main__'外部 def receiveWriter(cb): while True: n = random.randint(5,20) cb.receive(n) def ReplicatorReader(cb): while True: cb.replicator() def journalerReader(cb): while True: cb.journaler() def unmarshallerReader(cb): while True: cb.unmarshaller() def consumeReader(cb): while True: print(cb.consume()) if __name__ == '__main__': cb = disruptor.CircularBuffer(5) # 若CircularBuffer支持跨进程传递可直接作为参数传入,不支持则替换为多进程共享结构 p0 = multiprocessing.Process(name="p0",target=receiveWriter, args=(cb,)) p0.start() p1 = multiprocessing.Process(name="p1",target=ReplicatorReader, args=(cb,)) p1.start() p2 = multiprocessing.Process(name="p2",target=journalerReader, args=(cb,)) p2.start() p3 = multiprocessing.Process(name="p3",target=unmarshallerReader, args=(cb,)) p3.start() p4 = multiprocessing.Process(name="p4",target=consumeReader, args=(cb,)) p4.start()
内容的提问来源于stack exchange,提问作者Ehsan Akbar
相关产品推荐
相关产品推荐

