使用管道的多处理脚本
multiprocessing script using Pipes
当我尝试 运行 以下脚本时,进程 1 仅显示 1 秒的视频并卡住。代码有什么问题吗?我的目标是 运行 两个进程,一个连续显示帧,另一个进程执行人脸检测并在 process1 设置事件时打印结果。进程 1 定期设置事件,即每 20 或 30 帧之后。
def read(e,parent):
fps,st,frames_to_count,cnt = (0,0,30,0)
vid = cv2.VideoCapture('sample.mp4')
wid = 640
while(vid.isOpened()):
res,frame = vid.read()
if not res:
break
frame = imutils.resize(frame,width = wid)
cv2.imshow('VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
parent.send(frame)
e.set()
st=time.time()
cnt=0
except:
pass
cnt+=1
cv2.destroyAllWindows()
def fd(e,child):
face_cascade=cv2.CascadeClassifier("path to xml")
while True:
e.wait()
faces=face_cascade.detectMultiScale(child.recv(),1.1,4)
print(faces)
e.clear()
def main():
e = Event()
(child,parent) = Pipe()
p1 = Process(target=read, args=(e,parent))
p2 = Process(target=fd, args=(e,child))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == "__main__":
main()
查看我对您发布的问题的所有评论。在下面的代码中,我保留了您正在使用的 Pipe
但指定了 duplex=False 因为您没有使用返回的连接进行 two-way 通信并且有相应地将这些连接从 child
和 parent
重命名为现在更有意义的 read_conn
和 send_conn
。当然,我已经删除了 Event
实例。
由于 fd
似乎处于一个永不终止的循环中,main
将永远无法 join
该过程。因此,p2
应创建为 守护进程 进程,当所有 non-daemon 进程和线程终止时,该进程将自动终止。
def read(send_conn):
fps,st,frames_to_count,cnt = (0,0,30,0)
vid = cv2.VideoCapture('sample.mp4')
wid = 640
while(vid.isOpened()):
res,frame = vid.read()
if not res:
break
frame = imutils.resize(frame,width = wid)
cv2.imshow('VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
send_conn.send(frame)
st=time.time()
cnt=0
except:
pass
cnt+=1
cv2.destroyAllWindows()
def fd(recv_conn):
face_cascade=cv2.CascadeClassifier("path to xml")
while True:
faces=face_cascade.detectMultiScale(recv_conn.recv(),1.1,4)
print(faces)
def main():
(recv_conn,send_conn) = Pipe(duplex=False)
p1 = Process(target=read, args=(send_conn,))
p2 = Process(target=fd, args=(recv_conn,), daemon=True)
p1.start()
p2.start()
p1.join()
if __name__ == "__main__":
main()
当我尝试 运行 以下脚本时,进程 1 仅显示 1 秒的视频并卡住。代码有什么问题吗?我的目标是 运行 两个进程,一个连续显示帧,另一个进程执行人脸检测并在 process1 设置事件时打印结果。进程 1 定期设置事件,即每 20 或 30 帧之后。
def read(e,parent):
fps,st,frames_to_count,cnt = (0,0,30,0)
vid = cv2.VideoCapture('sample.mp4')
wid = 640
while(vid.isOpened()):
res,frame = vid.read()
if not res:
break
frame = imutils.resize(frame,width = wid)
cv2.imshow('VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
parent.send(frame)
e.set()
st=time.time()
cnt=0
except:
pass
cnt+=1
cv2.destroyAllWindows()
def fd(e,child):
face_cascade=cv2.CascadeClassifier("path to xml")
while True:
e.wait()
faces=face_cascade.detectMultiScale(child.recv(),1.1,4)
print(faces)
e.clear()
def main():
e = Event()
(child,parent) = Pipe()
p1 = Process(target=read, args=(e,parent))
p2 = Process(target=fd, args=(e,child))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == "__main__":
main()
查看我对您发布的问题的所有评论。在下面的代码中,我保留了您正在使用的 Pipe
但指定了 duplex=False 因为您没有使用返回的连接进行 two-way 通信并且有相应地将这些连接从 child
和 parent
重命名为现在更有意义的 read_conn
和 send_conn
。当然,我已经删除了 Event
实例。
由于 fd
似乎处于一个永不终止的循环中,main
将永远无法 join
该过程。因此,p2
应创建为 守护进程 进程,当所有 non-daemon 进程和线程终止时,该进程将自动终止。
def read(send_conn):
fps,st,frames_to_count,cnt = (0,0,30,0)
vid = cv2.VideoCapture('sample.mp4')
wid = 640
while(vid.isOpened()):
res,frame = vid.read()
if not res:
break
frame = imutils.resize(frame,width = wid)
cv2.imshow('VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
send_conn.send(frame)
st=time.time()
cnt=0
except:
pass
cnt+=1
cv2.destroyAllWindows()
def fd(recv_conn):
face_cascade=cv2.CascadeClassifier("path to xml")
while True:
faces=face_cascade.detectMultiScale(recv_conn.recv(),1.1,4)
print(faces)
def main():
(recv_conn,send_conn) = Pipe(duplex=False)
p1 = Process(target=read, args=(send_conn,))
p2 = Process(target=fd, args=(recv_conn,), daemon=True)
p1.start()
p2.start()
p1.join()
if __name__ == "__main__":
main()