TL; DR:多处理共享阵列使用Python 2工作正常,但它们使用Python 3随机挂起(几秒钟)。我在RPi3上运行代码。
我正在为Raspberry Pi 3编写视频捕获代码,我需要有两个256帧的视频缓冲区,这些视频缓冲区是交替的。当一个缓冲区被填充时,另一个缓冲区正在另一个线程中处理。
我已经成功地使用Python 2做了多年,但最近我将所有内容移植到Python 3.然后我注意到很多帧都被丢弃,看似随机。
以下是我用于测试的代码:
from __future__ import print_function, division
import numpy as np
import time
import multiprocessing
import ctypes
class BufferedCapture(multiprocessing.Process):
running = False
def __init__(self, array1, array2):
super(BufferedCapture, self).__init__()
self.array1 = array1
self.array2 = array2
def startCapture(self):
""" Start capture using the specified camera.
"""
self.exit = multiprocessing.Event()
self.start()
def stopCapture(self):
""" Stop capture.
"""
self.exit.set()
self.join()
def run(self):
assignment_times = []
for i in range(256):
print(i)
# Assign arrays to video frames (in this case, use placeholder values)
t1 = time.time()
self.array1[i, :1200, :700] = np.ones((1200, 700), dtype=np.uint8)*3
assignment_times.append(time.time() - t1)
t1 = time.time()
self.array2[i, :1200, :700] = np.ones((1200, 700), dtype=np.uint8)*5
assignment_times.append(time.time() - t1)
print('Max assignment time:', max(assignment_times))
print('Avg assignemnt time:', sum(assignment_times)/len(assignment_times))
if __name__ == "__main__":
import multiprocessing.sharedctypes
width = 1280
height = 720
array_pad = 1
# Init shared arrays
array_size = 256*(width + array_pad)*(height + array_pad)
array1_ctypes = multiprocessing.sharedctypes.RawArray(ctypes.c_uint8, array_size)
array1 = np.frombuffer(array1_ctypes, dtype=np.uint8, count=array_size)
array1.shape = (256, width + array_pad, height + array_pad)
array2_ctypes = multiprocessing.sharedctypes.RawArray(ctypes.c_uint8, array_size)
array2 = np.frombuffer(array2_ctypes, dtype=np.uint8, count=array_size)
array2.shape = (256, width + array_pad, height + array_pad)
bc = BufferedCapture(array1, array2)
print('Starting')
# Start buffered capture
bc.startCapture()
print('Stopping')
bc.stopCapture()
print(array1)
print('_________________')
print(array2)
在使用Python 2.7运行代码之后,就会报告:
Max assignment time: 0.0120410919189
Avg assignment time: 0.0102647687308
一切都很好。
另一方面,这是我用Python 3.6获得的:
Max assignment time: 5.458962678909302
Avg assignment time: 0.07329284632578492
进一步分析后,我注意到数组赋值只是随机挂起,而大多数情况下它的速度相当快,但速度不如Python 2快。
我还注意到,使用Python 3在一开始就需要很长时间(~10s)来启动数组,而Python 2基本上是即时的。
我完全被这个难过,有没有人知道这里发生了什么?
谢谢!
P.S。 这段代码是我的低成本流星相机项目的一部分,如果有人有兴趣,这里是GitHub回购:https://github.com/CroatianMeteorNetwork/RMS
更新
我在运行Linux Mint 18.1的笔记本电脑上进行了测试,Python 2和3的运行速度同样快。这是Raspberry Pi特有的问题。