如何通过Python读取/轮询子进程输出的实时传感器数据?
解决方案
1. 是否应该用subprocess方案?
完全应该。subprocess是Python官方提供的管理外部进程的标准工具,刚好适配你这种需要启动持续运行的Java程序、实时捕获其输出并处理的场景,没有比这更合适的方案。
2. 如何配置subprocess?
你之前用subprocess.run的问题在于,这个方法会等待外部进程完全结束后才返回结果,但你的Java程序是持续输出传感器数据的长期进程,所以永远不会触发run的返回,导致程序卡住。正确的做法是用subprocess.Popen,它启动进程后立即返回,让你能实时读取输出。
另外要注意:Java默认会对stdout做行缓冲,可能导致你无法及时拿到数据。如果没法修改Java代码添加System.out.flush(),可以在Python端开启文本模式按行读取,确保实时获取输出。
以下是可行的代码示例:
import subprocess # 启动Java进程,开启文本模式按行读取输出 proc = subprocess.Popen( ['java', '-jar', 'myjavajar.jar', '-port', '/dev/ttyUSB3', '-baud', '115200', '-flow', 'hardware'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True # 将输出转为字符串,替代旧版的universal_newlines=True ) try: # 实时遍历输出的每一行 for line in proc.stdout: line = line.strip() if not line: continue # 这里添加你的数据处理逻辑 print(f"捕获到输出: {line}") if line.startswith("SensorData"): # 解析传感器数据示例 raw_data = line.split('[')[1].split(']')[0].split(',') parsed_data = [int(num) for num in raw_data] print(f"解析后的数据: {parsed_data}") except KeyboardInterrupt: # 处理用户Ctrl+C终止的情况 print("\n正在终止Java进程...") finally: # 确保Java进程被终止 proc.terminate() proc.wait()
3. 确保Python进程关闭时Java进程也随之关闭
上面的示例通过try-finally块实现了核心需求:无论Python是正常结束还是因为异常(比如Ctrl+C)退出,finally块里的proc.terminate()都会执行,强制终止Java进程。如果terminate()不够彻底,还可以替换为proc.kill()来强制杀死进程。
如果需要覆盖更极端的退出场景(比如Python被强制杀死),可以注册atexit钩子:
import atexit def cleanup_java_proc(proc): if proc.poll() is None: # 检查进程是否仍在运行 proc.terminate() proc.wait() # 启动进程后注册清理函数 atexit.register(cleanup_java_proc, proc)
内容的提问来源于stack exchange,提问作者J B
相关产品推荐
相关产品推荐

