简体   繁体   中英

Starting and stopping a process

I am really having a hard time wrapping my head around multithreading in python. My expectation of the following code is that appLoop() will run for 10 seconds and the cease to exist -- which it does when tracing through in PyCharm, but not, when I just run it. This results in an infinite loop.

import time
import multiprocessing

isRunning = True
runningSince = 0

def appLoop():
    try:
        global isRunning
        while isRunning:
            time.sleep(1)
            global runningSince
            runningSince = runningSince + 1
            print(f'Looping since {runningSince} seconds.')
    except KeyboardInterrupt:
        print(f'appLoop stopped after {runningSince} seconds.')

class Process:
    class __Process:

        def __init__(self):
            self.process = multiprocessing.Process(target=appLoop)
            self.process.start()

    instance = None

    def __init__(self):
        if not Process.instance:
            Process.instance = Process.__Process()

    def __del__(self):
        print('Instance deleted.')

p = Process()
time.sleep(10)
isRunning = False
print(f'isRunning set to False.')
del p

This brings up (at least...) 2 questions for me:

  • why is process still running after del p -- am I creating a zombie process here?
  • why does my appLoop() keep running even after I set isRunning to false when I run the app (according to my observations this works when tracing through the code as mentioned above)?

My use case in the end is to be able to start / stop my appLoop() from a flask web interface -- which is why I am trying to implement a singleton here. Just in case you might wonder...

And: I do know that __del__ is not recommended as you never know when exactly garbage collection will call it -- in this case I just use it for (cave man) debugging.

isRunning = False changes the value of the variable in the parent process. The child process (the one that executes the while loop) has its own copy of isRunning that is not affected by the assignment.

For the same reason del p does not terminate the process: because it has its own copy of p . You should terminate the process explicitly in the destructor:

def __del__(self):
    print('Instance deleted.')
    Process.instance.process.terminate()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM