Python多进程实现树莓派响度计持续读数与音频录制并行执行问题求助
Python多进程实现树莓派响度计持续读数与音频录制并行执行问题求助
嘿,我完全懂你现在的困扰——想用多进程让响度计持续读数和音频录制并行跑,但目前要么没法真正并行,要么两个进程之间的触发信号根本传不通对吧?我来帮你捋捋问题出在哪,再给你个可行的解决方案。
首先,咱们先看看你现有代码里的两个核心问题:
1. 录制进程的启动方式不对
你在while u == 1循环里反复调用p2.start()和p2.join(),这会导致录制进程每次运行完就彻底结束,然后主进程才会重启它,而且join()会阻塞主进程,直到录制进程完成,这根本算不上真正的并行——相当于读数进程在跑,然后主进程时不时停下来等录制进程做完,再重启它,完全没达到你想要的“同时运行”的效果。
2. 普通列表没法在多进程间共享
Python的多进程是有独立内存空间的,你定义的那个用来存阈值触发记录的列表,每个子进程都会有自己的副本。也就是说,读数进程往自己的列表里加东西,录制进程看到的是另一个完全空的列表,自然不会触发录制操作。
解决思路:用进程安全的队列做通信,让两个进程持续运行
咱们换个方式:用multiprocessing.Queue来传递触发信号(队列是Python多进程自带的、安全的通信工具),让读数进程在检测到阈值时往队列里丢一个“要录制”的标记,录制进程则持续监听这个队列,一旦收到标记就启动10秒录制,录完继续等下一个信号。
同时,两个进程都用无限循环持续运行,不需要主进程反复重启它们。
给你改好的示例代码,你可以根据自己的实际传感器和音频录制逻辑调整:
import multiprocessing import time # 替换成你实际用的音频录制库(比如pyaudio、sounddevice) def record_10_seconds(): """模拟录制10秒音频的函数,替换成你的实际录制代码""" print("🔴 开始录制10秒音频...") # 这里写你的音频录制逻辑,比如用pyaudio打开流录制10秒 time.sleep(10) # 用sleep模拟录制时长 print("🟢 录制结束") def reading_values_from_loudness_meter(trigger_queue): """持续读取响度传感器值,超过阈值就往队列发信号""" while True: # 替换成你读取响度传感器的实际代码 current_loudness = 75 # 模拟传感器返回的响度值 threshold = 70 # 你的阈值 if current_loudness > threshold: print(f"检测到响度值{current_loudness}超过阈值,发送录制信号") trigger_queue.put(True) # 往队列丢触发标记 time.sleep(0.5) # 传感器读取间隔,根据你的硬件调整 def recording_audio(trigger_queue): """持续监听队列,收到信号就启动录制""" while True: # 阻塞等待队列里的信号,直到有消息才继续 need_record = trigger_queue.get() if need_record: record_10_seconds() # 可选:清空队列里可能堆积的信号(避免录制期间多次触发导致重复录制) while not trigger_queue.empty(): trigger_queue.get() if __name__ == "__main__": # 创建进程间通信的队列 trigger_queue = multiprocessing.Queue() # 创建两个子进程,把队列作为参数传进去 p1 = multiprocessing.Process(target=reading_values_from_loudness_meter, args=(trigger_queue,)) p2 = multiprocessing.Process(target=recording_audio, args=(trigger_queue,)) # 启动两个进程 p1.start() p2.start() # 让主进程等待子进程(按Ctrl+C可以终止程序) try: p1.join() p2.join() except KeyboardInterrupt: # 捕获终止信号,优雅结束子进程 p1.terminate() p2.terminate() print("\n程序已终止")
几个关键细节说明:
- 队列的安全性:
multiprocessing.Queue是线程/进程安全的,不用担心多个进程同时操作导致的问题,比共享列表靠谱多了。 - 录制后的队列清空:如果你的传感器在录制的10秒里还会多次触发阈值,队列里会堆积多个信号,录制完清空队列可以避免刚录完又立刻启动下一次录制(如果你希望每次触发都录,就去掉清空队列的代码)。
if __name__ == "__main__"::虽然树莓派是Linux系统不强制,但加上这个是Python多进程的规范写法,能避免一些奇怪的问题。- 音频录制的调整:把
record_10_seconds()里的time.sleep(10)换成你实际的录制代码就行,比如用pyaudio打开音频流,录制10秒后保存为文件。
这样调整后,两个进程就能真正并行运行了:读数进程持续检测响度,录制进程随时等待触发信号,互不干扰~
备注:内容来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

