gpt4 book ai didi

python-3.x - 与另一个线程或进程共享 asyncio.Queue

转载 作者:太空宇宙 更新时间:2023-11-03 22:40:27 25 4
gpt4 key购买 nike

我最近将我的旧模板匹配程序转换为 asyncio,并且我的一个协程依赖于阻塞方法 (processing_frame)。

每当调用该方法的协程 (analyze_frame) 从共享的 asyncio 获取项目时,我想在单独的线程或进程中运行该方法。队列()

我不确定这是否可行或是否值得性能明智,因为我在线程和多处理方面的经验很少

import cv2
import datetime
import argparse
import os
import asyncio

# Making CLI
if not os.path.exists("frames"):
os.makedirs("frames")

t0 = datetime.datetime.now()
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", required=True,
help="path to our file")
args = vars(ap.parse_args())

threshold = .2
death_count = 0
was_found = False
template = cv2.imread('youdied.png')
vidcap = cv2.VideoCapture(args["video"])

loop = asyncio.get_event_loop()
frames_to_analyze = asyncio.Queue()


def main():
length = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
tasks = []
for _ in range(int(length / 50)):
tasks.append(loop.create_task(read_frame(50, frames_to_analyze)))
tasks.append(loop.create_task(analyze_frame(threshold, template, frames_to_analyze)))
final_task = asyncio.gather(*tasks)
loop.run_until_complete(final_task)

dt = datetime.datetime.now() - t0
print("App exiting, total time: {:,.2f} sec.".format(dt.total_seconds()))

print(f"Deaths registered: {death_count}")


async def read_frame(frames, frames_to_analyze):
global vidcap
for _ in range(frames-1):
vidcap.grab()

else:
current_frame = vidcap.read()[1]
print("Read 50 frames")
await frames_to_analyze.put(current_frame)


async def analyze_frame(threshold, template, frames_to_analyze):
global vidcap
global was_found
global death_count
frame = await frames_to_analyze.get()
is_found = processing_frame(frame)
if was_found and not is_found:
death_count += 1
await writing_to_file(death_count, frame)
was_found = is_found


def processing_frame(frame):
res = cv2.matchTemplate(frame, template, cv2.TM_CCOEFF_NORMED)
max_val = cv2.minMaxLoc(res)[1]
is_found = max_val >= threshold
print(is_found)
return is_found


async def writing_to_file(death_count, frame):
cv2.imwrite(f"frames/frame{death_count}.jpg", frame)

if __name__ == '__main__':
main()

我试过使用 unsync但收效甚微
我会得到一些类似的东西

with self._rlock:
PermissionError: [WinError 5] Access is denied

最佳答案

如果 processing_frame 是一个阻塞函数,你应该用 await loop.run_in_executor(None, processing_frame, frame) 调用它。这会将函数提交到线程池并允许事件循环继续执行其他操作,直到调用函数完成。

cv2.imwrite 等调用也是如此。如所写,writing_to_file 不是真正的异步,尽管是用 async def 定义的。这是因为它不等待任何东西,所以一旦开始执行,它就会一直执行到最后,而不会暂停。在那种情况下,我们也可以首先将其设为一个普通函数,以明确发生了什么。

关于python-3.x - 与另一个线程或进程共享 asyncio.Queue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54371981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com