Legion
Legion

Reputation: 474

What's the most efficient way to pause a CPU-intensive python program?

I made a neural network (which has unfortunately grown in complexity and become rather CPU intensive) which analyzes screenshots in real-time.

I wish to pause it when I press the letter 'a' and un-pause it when the letter 'a' is pressed again. What is the most efficient way to pause it (without breaking the loop altogether)?

It uses Python OpenCV library, but I don't use cv2.imshow, hence I can't use cv2.Waitkey. I'm running this on Windows 10. Could you please provide example code to your answer? Here's a bit of the code:

import cv2
import mss
from PIL import Image
import numpy as np

#Creates an endless loop for high-speed image acquisition...
while (True):
    with mss.mss() as sct:
        # Get raw pixels from the screen
        sct_img = sct.grab(sct.monitors[1])

        # Create the Image
        img = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')

        #The rest of the neural network goes here...

        #PAUSE statement... 

Upvotes: 1

Views: 366

Answers (1)

tel
tel

Reputation: 13999

Use sigwait from the signal package in the Python standard library. sigwait won't work on Windows.

Edit

You can do what you want in a platform independent way by using the threading library. Here's a short example program (needs the py-getch package if you're running on Linux or Mac):

import os
from threading import Thread, Event

if os.name=='nt':
    from msvcrt import getch
elif os.name=='posix':
    from getch import getch
else:
    raise OSError

isRunning = True

def count(event):
    i = 0
    while isRunning:
        event.wait(1)

        if event.isSet() and isRunning:
            event.clear()
            print('Pausing count at %d' % i)
            event.wait()
            print('resuming count')
            event.clear()

        i += 1

def listener(event):
    # in Python, need to mark globals if writing to them
    global isRunning

    while isRunning:
        c = getch()
        if c=='a':
            event.set()
        if c=='e':
            event.set()
            isRunning = False

def main():
    pauseEvent = Event()
    pauseEvent.clear()

    listenerThread = Thread(target=listener, args=(pauseEvent,))

    listenerThread.start()
    count(pauseEvent)

if __name__=='__main__':
    main()

The above program will run two threads. The main thread will run the count function, which adds 1 to a count every second. The other thread runs the listener function, which will wait for user input. If type a, the listener thread will tell the count thread to pause and print out the current count. You can type a again to resume the count, or you can type e to quit.

Upvotes: 2

Related Questions