python hanging on closing/terminating multi-process task. Only stops via CTRL+Break

Viewed 55

I'm using multiprocess for screen grab to record keyboard actions and mouse movement associated with the image frame.

After saving, imshow window is to close and the multi process task should terminate, however after saving and closing the imshow window my CMD prompt hangs until I CTRL+Break.

If don't CTRL+Break and just close CMD prompt it appears the multi process task are still live in my task manager.

I know I'm missing .join() and .close() I'm just unsure how to add them in. Every time I try I get VAR not defined. If anyone could take a look at my code and suggest changes that would be greatly appreciated.

import os
import cv2
import mss
import time
import pydirectinput
import multiprocessing
import numpy as np

from utils.getkeys import key_check
from distutils.version import StrictVersion
from multiprocessing import Pipe

win_title = "ML Collection"
fps = 0
fps_dptime = 2
start_time = time.time()
sct = mss.mss()

image_data = "./data/image_data.npy"
keyPress_data = "./data/keyP_data.npy"
position_data = "./data/pos_data.npy"

def create_data():
    if os.path.isfile("./data/image_data.npy"):
        print("Loading previous data")
        img_data = list(np.load(image_data, allow_pickle=True))
        keyP_data = list(np.load(keyPress_data, allow_pickle=True))
        pos_data = list(np.load(position_data, allow_pickle=True))
    else:
        print("No previous files found. Creating new data files")
        img_data = []
        keyP_data = []
        pos_data = []
    return img_data, keyP_data, pos_data

img_data, keyP_data, pos_data = create_data()

def save_data(img_data, keyP_data, pos_data):
    np.save(image_data, img_data)
    np.save(keyPress_data, keyP_data)
    np.save(position_data, pos_data)


def get_screen(s):
    while True:
      screen = np.array(
          sct.grab({"top": 40, "left": 0, "width": 1280, "height": 800})
          )
      s.put_nowait(screen)
      s.join()
      
def mss_screen(s):
    global fps, start_time
    while True:
      if not s.empty():
        screen = s.get_nowait()
        s.task_done()
        screen = cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY)
##        screen = cv2.Canny(screen, threshold1=119, threshold2=250)
        screen = cv2.resize(screen, (244, 244))
        cv2.imshow(win_title, screen)

        img_data.append(screen)
        keys = key_check()
        keyP_data.append(keys)
        mpos = pydirectinput.position()
        pos_data.append(mpos)
        
        fps+=1
        fpstime = time.time() - start_time
        if (fpstime) >= fps_dptime :
          print("FPS: ", fps / (fpstime))
          fps = 0
          start_time= time.time()
          print("Press Numpad+ to close")
        if cv2.waitKey(1) & 0xFF == ord("+"):
            cv2.destroyAllWindows()
            save_data(img_data, keyP_data, pos_data)
            s1.close()
            s2.close()
            break
        
if __name__=="__main__":
    s = multiprocessing.JoinableQueue()

    s1 = multiprocessing.Process(target=get_screen, args=(s,))
    s2 = multiprocessing.Process(target=mss_screen, args=(s,))  

    s1.start()
    s2.start()
1 Answers

solved by changing:

fps+=1
    fpstime = time.time() - start_time
    if (fpstime) >= fps_dptime :
      print("FPS: ", fps / (fpstime))
      fps = 0
      start_time= time.time()
      print("Press P to close")
    if cv2.waitKey(1) & 0xFF == ord("+"):
        cv2.destroyAllWindows()
        save_data(img_data, keyP_data, pos_data)
        s1.close()
        s2.close()
        break
    
if __name__=="__main__":
    s = multiprocessing.JoinableQueue()

    s1 = multiprocessing.Process(target=get_screen, args=(s,))
    s2 = multiprocessing.Process(target=mss_screen, args=(s,))  

    s1.start()
    s2.start()

Changed to

    killKey = key_check()
    fps+=1
    fpstime = time.time() - start_time
    if (fpstime) >= fps_dptime :
      print("FPS: ", fps / (fpstime))
      fps = 0
      start_time= time.time()
      print("Press Numpad+ to close")
    if killKey == 'P':
        cv2.destroyAllWindows()
        save_data(img_data, keyP_data, pos_data)
        break
    
if __name__=="__main__":
     s = multiprocessing.JoinableQueue()

     s1 = multiprocessing.Process(target=get_screen, args=(s,))
     s2 = multiprocessing.Process(target=mss_screen, args=(s,))  

     s1.start()
     s2.start()
     while True:
         killKey = key_check()
            if killKey == 'P':
               time.sleep(1)
               s1.terminate()
               s2.terminate()
               break
Related