python - Python - 子流程 - 记录和转储测量值
问题描述
在带有 Ubuntu 16.04LTS 的 python3 中,我有一个从主脚本创建的子进程,用于记录连接到本地计算机的设备的测量值。我想知道当我想完成数据记录时如何向这个子进程发送消息,并切换到将测量值转储到 csv 文件。下面显示的是我迄今为止尝试过的精简版本,但代码挂起,我无法转储我记录的测量值。事实上,我只记录了 1 个测量值。我不确定如何在记录数据时异步检查标准输入。可以请我帮忙吗?
主文件
# start subprocess
p_1 = subprocess.Popen(["./ekg.py", saveFilename_ekg], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# do other stuff
...
# send message to quit
message = str("1")
encMsg = message.encode()
print("Message:", encMsg.decode())
p_stdout = p_1.communicate(input=encMsg)[0]
# print "Done" from subprocess
print(p_stdout.decode('utf-8').strip())
# kill subprocess
p_1.kill()
ekg.py
def dumpLiveData(outputFile):
ekg = ekgClass()
dataMeasurements = []
for liveData in ekg.getLiveData():
# monitor stdin for message
if int(sys.stdin.read()) == 1:
break
else:
meas = [liveData.time, liveData.pulseWaveform]
dataMeasurements.append(meas)
#print ("Dumping data")
with open(outputFile, 'wb') as csvfile:
writer = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC)
#print ("Created text file")
header = ["Time", "Waveform value"]
writer.writerow(header)
for idx, val in enumerate(dataMeasurements):
writer.writerow(dataMeasurements[idx])
print("Done")
if __name__== "__main__":
# get parameters
parser = argparse.ArgumentParser(description="ekg.py")
parser.add_argument("outputFile", help="Output CSV file.")
# parse
args = parser.parse_args()
# record and dump measurements
dumpLiveData(args.outputFile)
解决方案
通过向子进程发送控制 + C 事件来解决它。一个 try-except-else 块捕获了键盘中断,对其进行了处理,然后我优雅地退出了该块。退出后,我将记录的数据写入 csv 文件。
主文件
import subprocess, signal
# start subprocess
p_1 = subprocess.Popen(["./ekg.py", saveFilename_ekg], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# do other stuff
...
# send control + C event
p_1.send_signal(signal.SIGINT)
stdout, stderr = p_1.communicate(input=encMsg)[0]
# print output from subprocess
print(stdout.decode('utf-8').strip())
# wait for subprocess to write file
p_1.wait()
# kill subprocess
p_1.kill()
ekg.py
def dumpLiveData(outputFile):
ekg = ekgClass()
dataMeasurements = []
exception_found = None
try:
for liveData in ekg.getLiveData():
if exception_found == True:
break
meas = [liveData.time, liveData.pulseWaveform]
dataMeasurements.append(meas)
except KeyboardInterrupt:
exception_found = True
else:
pass
print ("Dumping data")
with open(outputFile, 'wb') as csvfile:
writer = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC)
print ("Created text file")
header = ["Time", "Waveform value"]
writer.writerow(header)
for idx, val in enumerate(dataMeasurements):
writer.writerow(dataMeasurements[idx])
print("Done")
推荐阅读
- java - 在Android中做片段的正确方法是什么?
- symfony - 尝试将记录器绑定到 Symfony 3.4 中的自动装配控制器构造函数时出现未使用的绑定错误
- pagespeed - 为什么 Google PageSpeed Insights 不一致
- c# - 如何复制和替换具有管理员权限的所有用户配置文件的文件
- html - 使用 base64 字符串的剃刀显示图像
- c# - 重置 OnMessageReceived 后 RabbitMQ 不检索消息
- macos - 在 NSTableView 中显示数组的元素
- reactjs - 三元条件 - 尝试添加类错误
- angular - AGM Angular Google Maps 图像未加载
- sql-server - 从 SS2019 CTP2.2 创建外部数据源不起作用