Python ADC采集项目中主进程向其他脚本安全传输数据的方案咨询
ADC数据采集进程间通信方案分析
中间文件方案可行性
中间文件方案可以实现需求,但仅适合采样频率极低的场景,不推荐用于实时性要求高的ADC采集:
- 优势:实现简单,进程完全解耦,子进程崩溃不会直接影响主采集逻辑
- 缺陷:
- 磁盘IO延迟高,高频采样下容易出现数据堆积、丢数,无法满足实时性要求
- 多进程读写需要额外处理文件锁逻辑,实现繁琐
- 长时间运行容易生成大量碎片文件,占用磁盘空间
最优方案推荐
优先选择内存级发布-订阅通信模式,既能保证进程完全解耦,又能满足实时性要求,Python生态下有两种成熟实现可选:
1. 内置multiprocessing.Queue(轻量场景首选)
如果两个子脚本由主程序直接启动,用Python标准库自带的多进程队列成本最低:
- 主程序作为生产者,为两个子进程各创建一个独立队列,保证两个子进程都能拿到全量采集数据
- 队列是内存级通信,延迟在微秒级,完全满足实时采集需求
- 主程序写队列时使用非阻塞模式,搭配异常捕获即可保证子进程崩溃、队列堆满时不会阻塞主采集逻辑
- 核心代码示例:
# 主程序侧实现 from multiprocessing import Process, Queue # 为两个子进程分别创建独立队列,设置队列长度避免内存溢出 format_queue = Queue(maxsize=1024) network_queue = Queue(maxsize=1024) # 启动子进程 format_worker = Process(target=格式转换脚本入口函数, args=(format_queue,), daemon=True) network_worker = Process(target=网络服务脚本入口函数, args=(network_queue,), daemon=True) format_worker.start() network_worker.start() # ADC采集主循环 while True: adc_sample = 执行ADC采样() # 替换为你的采集逻辑 # 非阻塞写队列,子进程异常时直接跳过不阻塞采集 try: format_queue.put(adc_sample, block=False) except: # 队列满时可按业务需求选择丢旧数据或丢新数据 pass try: network_queue.put(adc_sample, block=False) except: pass
2. ZeroMQ PUB-SUB模式(高可用灵活场景首选)
如果子脚本需要独立启停、甚至跨设备部署,优先用ZeroMQ的发布订阅模式:
- 主程序作为发布端绑定本地端口,采集到数据后直接对外发布,不需要关心是否有订阅端、订阅端是否正常运行
- 两个子脚本作为订阅端连接主程序端口,自主接收全量采集数据
- 完全解耦,子进程崩溃、断连完全不会影响主程序采集逻辑,不需要额外做异常处理
- 内存级通信延迟和内置队列相当,性能足够,底层自动处理缓冲,不需要手动处理锁、队列溢出问题
- 扩展性极强,后续新增消费进程不需要修改主程序任何代码
- 核心代码示例(需先安装
pyzmq依赖):
# 主程序(发布端) import zmq context = zmq.Context() pub_socket = context.socket(zmq.PUB) pub_socket.bind("tcp://127.0.0.1:5555") while True: adc_sample = 执行ADC采样() # 直接发布数据,不需要关心订阅端状态 pub_socket.send_pyobj(adc_sample)
# 子脚本(订阅端,格式转换/网络服务逻辑通用) import zmq context = zmq.Context() sub_socket = context.socket(zmq.SUB) sub_socket.connect("tcp://127.0.0.1:5555") # 订阅所有发布的消息 sub_socket.setsockopt_string(zmq.SUBSCRIBE, "") while True: adc_sample = sub_socket.recv_pyobj() # 执行对应的格式转换/网络服务逻辑
如果你的采样频率极低(低于1Hz),也可以选择Redis发布订阅等方案,但整体重量高于ZeroMQ,没有额外需求不推荐使用。
内容的提问来源于stack exchange,提问作者Nahum Mendez Chazarra
相关产品推荐
相关产品推荐

