使用RaspberryPi系统,我必须同步一个Raspbian系统命令( raspivid -t 20000 )和一个从传感器连续读取的while循环,并将样本存储在一个数组中。 Raspbian命令通过RaspberryPi相机CSI模块开始videologging,我必须确保它在传感器采集的同一时刻开始。 我看到很多解决scheme让我在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循环只有在os.system()函数完成时才会运行。 但正如我上面写的,我需要这两个进程是同步的,并行工作。 任何build议?
只需在最后添加一个& ,以使进程分离到后台:
os.system("raspivid -t 20000 /home/pi/test.h264 &")
根据bash手册页:
如果一个命令被控制操作符&终止,那么shell在一个子shell中在后台执行命令。 shell不会等待命令完成,返回状态为0。
另外,如果你想最小化执行raspivid之后启动循环的时间,你应该在调用之前分配你的data和raspivid :
data = np.zeros(20000, dtype="float") indx=0 os.system("raspivid -t 20000 /home/pi/test.h264 &") while True: # ....
更新:
由于我们在评论中进一步讨论,显然没有必要在“同时”启动“ raspivid ” 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!"
你可以重写你的代码:
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)
raspivid subprocess.Popen()返回而不等待raspivid结束。