使用RaspberryPi系统,我必须将Raspbian系统命令(raspivid -t 20000
)与从传感器连续读取的while循环同步,并将数据存储在数组中。 Raspbian命令通过RaspberryPi摄像机CSI模块启动视频录制,我必须确保它在传感器采集的同一时刻开始。我看到很多解决方案让我在multiprocessing
,threading
,subprocess
,ecc等模块中感到困惑。到目前为止,我唯一理解的是os.system()
函数阻止执行以下python命令,只要它运行就放在脚本中。所以,如果我尝试:
import os
import numpy as np
os.system("raspivid -t 20000 /home/pi/test.h264")
data = np.zeros(20000, dtype="float") #memory pre-allocation supposing I have to save 20000 samples from the sensor (1 for each millisecond of the video)
indx=0
while True:
sens = readbysensor() #where the readbysensor() function is defined before in the script and reads a sample from the sensor
data[indx]=sens
if indx==19999:
break
else:
indx+=1
while-loop仅在os.system()
函数完成时运行。但正如我上面所写,我需要两个进程同步并且并行工作。有什么建议吗?
答案 0 :(得分:2)
最后添加一个&
,以使进程分离到后台:
os.system("raspivid -t 20000 /home/pi/test.h264 &")
根据bash
手册页:
如果命令由控制操作员&,shell终止 在子shell中在后台执行命令。外壳确实如此 不要等待命令完成,返回状态为0。
此外,如果您希望最小化循环在执行raspivid
后开始所需的时间,则应在呼叫前分配data
和indx
:
data = np.zeros(20000, dtype="float")
indx=0
os.system("raspivid -t 20000 /home/pi/test.h264 &")
while True:
# ....
<强>更新强>
由于我们在评论中进一步讨论过,很明显没有必要像raspivid
那样“同时”启动循环(无论这意味着什么),因为如果你试图从中读取数据I2C并确保您不会遗漏任何数据,您最好在运行raspivid
之前开始读取操作。通过这种方式,您可以确定在此期间(无论这两次执行之间存在多大延迟),您都不会错过任何数据。
考虑到这一点,您的代码可能如下所示:
data = np.zeros(20000, dtype="float")
indx=0
os.system("(sleep 1; raspivid -t 20000 /home/pi/test.h264) &")
while True:
# ....
这是我们在运行raspivid
之前添加1秒延迟的最简单版本,因此我们有时间进入while
循环并开始等待I2C数据。
这有效,但它不是生产质量代码。为了获得更好的解决方案,请在一个线程中运行数据采集功能,在第二个线程中运行raspivid
,保留启动顺序(首先启动读取线程)。
像这样:
import Queue
import threading
import os
# we will store all data in a Queue so we can process
# it at a custom speed, without blocking the reading
q = Queue.Queue()
# thread for getting the data from the sensor
# it puts the data in a Queue for processing
def get_data(q):
for cnt in xrange(20000):
# assuming readbysensor() is a
# blocking function
sens = readbysensor()
q.put(sens)
# thread for processing the results
def process_data(q):
for cnt in xrange(20000):
data = q.get()
# do something with data here
q.task_done()
t_get = threading.Thread(target=get_data, args=(q,))
t_process = threading.Thread(target=process_data, args=(q,))
t_get.start()
t_process.start()
# when everything is set and ready, run the raspivid
os.system("raspivid -t 20000 /home/pi/test.h264 &")
# wait for the threads to finish
t_get.join()
t_process.join()
# at this point all processing is completed
print "We are all done!"
答案 1 :(得分:2)
您可以将代码重写为:
import subprocess
import numpy as np
n = 20000
p = subprocess.Popen(["raspivid", "-t", str(n), "/home/pi/test.h264"])
data = np.fromiter(iter(readbysensor, None), dtype=float, count=n)
subprocess.Popen()
在不等待raspivid
结束的情况下立即返回。