0

Context: I am creating a tkinter project that includes face recognition. Because import face_recognition, cv2takes a long time, to make it more convenient, this has been placed in a thread (I know tkinter doesn't like threads but they are very useful). E.g.

import tkinter
def thread_import ():
    global face_recognition, cv2
    import face_recognition, cv2
if __name__ == '__main__':
    threading.Thread (target = thread_import).start ()

My question is that is there a way to lower the impact of the import. Due to the thread hogging CPU time, my tkinter window can behave unresponsively. I don't mind if it takes slightly longer but I don't really want to go into all the library files to add time.sleep (x).

Many thanks in advance.

Minion Jim
  • 1,239
  • 13
  • 30
  • I don't understand last sentence. Based on what I *think* I understand, I would try splitting import statement into 2 import statements. – Terry Jan Reedy Sep 09 '18 at 17:04
  • If your app does things other than face recognition, you could delay the import until face recognition is requested. – Terry Jan Reedy Sep 09 '18 at 17:06
  • I was meaning to go into `__init__` file for open-cv and face recognition and then do as you suggested with `time.sleep` between each import (and then possibly for each file called from there). – Minion Jim Sep 09 '18 at 17:07
  • I could delay the import but it is much more user-friendly if they don't have to wait for that (hence why I didn't import it when first loading the program) – Minion Jim Sep 09 '18 at 17:09
  • If face_recognition is written in C, it probably should be releasing the GIL to allow the main thread to run. This comment is at the edge of my knowledge, so I cannot say more, except to search the 'python' tag for GIL and possibly ask for help on python-list. – Terry Jan Reedy Sep 10 '18 at 15:40

1 Answers1

0

Many thanks to @TerryJanReedy for his comment about GIL. Based on this, I set up a multiproccessing.Process object and passed the necessary values through a multiprocessing.Manager object. An example implementation can be seen below:

import multiprocessing, time

def thread_manager (manager):
    import face_recognition, cv2
    while not manager ["closing"]:
        if manager ["com"] == 0: time.sleep (0.2)
        else:
            if manager ["com"] == 1: manager ["rtn"] = "Example return."
            manager ["com"] = 0

if __name__ == "__main__":
    manager = multiprocessing.Manager ().dict ({"com" : 0, "closing" : False, "rtn" : None})
    p = multiprocessing.Process (target = thread_manager, args = (manager,))
    p.start ()
    time.sleep (5)
    manager ["com"] = 1
    while manager ["rtn"] == None: time.sleep (0.2)
    print (manager ["rtn"])
    manager ["closing"] = True
Minion Jim
  • 1,239
  • 13
  • 30