如何让 thread/process 始终处于活动状态并在另一个 thread/process 中每隔一定时间间隔请求其变量之一的更新值

How to have a thread/process always active and request the updated value of one of its variables every certain time interval in another thread/process

import numpy as np
import cv2

import multiprocessing
import time
import random

finish_state = multiprocessing.Event()

#function that requests frames
def actions_func(frame):
    while True:
        time.sleep(random.randint(1,5))
        cv2.imshow('requested_frame_1',frame)

        time.sleep(random.randint(1,5))
        cv2.imshow('requested_frame_2',frame)

        if cv2.waitKey(1) & 0xFF == ord('q'): break

#function that keeps the camera always on and should return the frame value with the last image only when requested
def capture_cam():
    cap = cv2.VideoCapture(1)

    if (cap.isOpened() == False): 
        print("Unable to read camera feed")

    # Default resolutions of the frame are obtained. The default resolutions are system dependent.
    # We convert the resolutions from float to integer.
    frame_width = int(cap.get(3))
    frame_height = int(cap.get(4))


    while(True):
        ret, frame = cap.read()

        if ret == True: 
            cv2.imshow('frame',frame)

            if cv2.waitKey(1) & 0xFF == ord('q'): break

        else:
            break  


def main_process(finish_state):

    thr1, frame = multiprocessing.Process(target=capture_cam)
    thr1.start()

    thr2 = multiprocessing.Process(target=actions_func, args=(frame,))
    thr2.start()


if __name__ == '__main__':
    main_process(finish_state)

print("continue the code with other things after all threads/processes except the main one were closed with the loop that started them... ")

我希望网络摄像头始终处于打开状态以捕获图像,为此我创建了线程 1,无论程序如何,它都应该一直 运行。 你需要的是修复这个程序,它应该从线程 1 上总是 运行s 的函数中请求帧。 问题是我不知道什么时候可以向 thread1 询问它显示的最后一帧,并表示我放置了 random.randint(1,5),尽管实际上我不知道最大值或从 thread1

请求最后一帧的最短时间

事实上,我对这个程序越来越复杂了,我真的不知道创建一个线程 2 来执行帧请求是否方便,或者只使用线程 1 和帧请求是否更好在主线程中

虽然说是线程,其实是并行进程,用线程试试,我觉得还是用进程更方便吧?

Traceback (most recent call last):
  File "request_frames_thread.py", line 58, in <module>
    main_process(finish_state)
  File "request_frames_thread.py", line 50, in main_process
    thr1, frame = multiprocessing.Process(target=capture_cam)
TypeError: cannot unpack non-iterable Process object

我会让主进程创建一个全双工 multiprocessing.Pipe 实例,其中 returns 两个 multiprocessing.connection.Connection 实例并将一个连接传递给每个进程。这些连接可用于一种简单的双向通信工具,用于相互发送和接收对象。我会让 capture_cam 进程启动一个 dameon 线程(它将在所有 regular 线程终止时终止,因此它可以在一个无限循环)传递给这些连接以处理对存储在全局变量中的最新帧的请求。

唯一的要求是帧可由 pickle 模块序列化。

import multiprocessing
from threading import Thread
import time
import random


#function that requests frames
def actions_func(conn):
    try:
        while True:
            time.sleep(random.randint(1,5))
            # Ask for latest frame by sending any message:
            conn.send('frame')
            frame = conn.recv() # This is the response
             cv2.imshow('requested_frame_1',frame)

            time.sleep(random.randint(1,5))
            # Ask for latest frame by sending any message:
            conn.send('frame')
            frame = conn.recv() # This is the response
            cv2.imshow('requested_frame_2',frame)

            if cv2.waitKey(1) & 0xFF == ord('q'): break
    except BrokenPipeError:
        # The capture_cam process has terminated.
        pass

def handle_frame_requests(conn):
    try:
        while True:
            # Any message coming in is a request for the latest frame:
            request = conn.recv()
            conn.send(frame) # The frame must be pickle-able
    except EOFError:
        # The actions_func process has ended
        # and its connection has been closed.
        pass

#function that keeps the camera always on and should return the frame value with the last image only when requested
def capture_cam(conn):
    global frame

    frame = None

    # start dameon thread to handle frame requests:
    Thread(target=handle_frame_requests, args=(conn,), daemon=True).start()

    cap = cv2.VideoCapture(1)

    if (cap.isOpened() == False):
        print("Unable to read camera feed")

    # Default resolutions of the frame are obtained. The default resolutions are system dependent.
    # We convert the resolutions from float to integer.
    frame_width = int(cap.get(3))
    frame_height = int(cap.get(4))


    while(True):
        ret, frame = cap.read()

        if ret == True:
            cv2.imshow('frame',frame)

            if cv2.waitKey(1) & 0xFF == ord('q'): break

        else:
            break


def main_process(finish_state):
    conn1, conn2 = multiprocessing.Pipe(duplex=True)

    p1 = multiprocessing.Process(target=capture_cam, args=(conn1,))
    p1.start()

    p2 = multiprocessing.Process(target=actions_func, args=(conn2,))
    p2.start()


if __name__ == '__main__':
    finish_state = multiprocessing.Event()
    main_process(finish_state)