mak47
mak47

Reputation: 303

Runtime error when trying to spawn multiple processes (image detection and print to terminal)

I was following this guide to try and see if I could get a simple multiprocessing script to run. It's been discussed in other questions that I need to use multiprocessing for what I'm trying to achieve.

For the sake of following the beginner guide, I wrote two functions.

import pyautogui as py
import multiprocessing

def print_i():
    for i in range(0, 21):
        print(i)
        sleep(0.1)

image = r'C:\Users\image.jpg'

def closeWindow():
    while True:
        found = py.locateCenterOnScreen(image)
            if found != None:
            py.click(1797, 134)

print_i prints out the numbers 0-20 and closeWindow checks if a particular window is open then clicks to close it if it finds it, both work individually.

In following the guide I've imported multiprocessing and done the following:

p1 = multiprocessing.Process(target= print_i)
p2 = multiprocessing.Process(target= closeWindow)

p1.start()
p2.start()

p1.join()
p2.join()

However, I immediately get following error twice:

RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

This stack explains that the multiprocessing module should take care of these cases and detect that you are trying to start new processes even before the target was run.

In reading the error in mentions not using fork to start a child process, I didn't think I had a child process, does anything after your first process count as a child process when multiprocessing? If yes, how can I output the numbers 0-20 with one process while running the image detection at the same time?

Upvotes: 0

Views: 477

Answers (1)

Cow
Cow

Reputation: 3040

There are lots of ways to schedule or run tasks continuously. Here are a few examples:

Using Threading:

from threading import Thread
from time import sleep

def run_close_window_task():
    while True:
        print("Hello, close window task is running!")
        sleep(2)

t = Thread(name='backgroundtask', target=run_close_window_task)
t.start()

print("Now we are doing other stuff, while the other task is running...")

NOTE: You have to kill the Python process via task manager in Windows to stop it.

Result:

Hello, close window task is running!
Now we are doing other stuff, while the other task is running...
Hello, close window task is running!
Hello, close window task is running!
Hello, close window task is running!
...

Using Asyncio:

from asyncio import sleep, run, create_task, gather

async def run_close_window_task():
    while True:
        print("Hello, close window task is running!")
        await sleep(2)

async def print_i():
    while True:
        for i in range(0, 21):
            print(f"Printing i: {str(i)}")
            await sleep(0.2)

async def main():
    tasks = [create_task(run_close_window_task()), create_task(print_i())]
    await gather(*tasks, return_exceptions=False)

if __name__ == "__main__":
    run(main())

Result:

Hello, close window task is running!
Printing i: 0
Printing i: 1
Printing i: 2
Printing i: 3
Printing i: 4
Printing i: 5
Printing i: 6
Printing i: 7
Printing i: 8
Printing i: 9
Hello, close window task is running!
Printing i: 10
Printing i: 11
Printing i: 12
Printing i: 13
Printing i: 14
Printing i: 15
Printing i: 16
Printing i: 17
Printing i: 18
Printing i: 19
...

Upvotes: 1

Related Questions