Lynix
Posts: 6
Joined: Mon Apr 27, 2020 7:16 pm

Python multiprocessing: terminate a process

Mon Jun 22, 2020 3:06 pm

I have this code:

Code: Select all

from flask import Flask, request, render_template
import RPi.GPIO as GPIO
import multiprocessing
import time
 
app = Flask(__name__)
pin = 17
btn = 22
 
def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.OUT)
    GPIO.setup(btn, GPIO.IN)
    GPIO.output(pin, GPIO.HIGH)
 
def main(hours, minutes, seconds):
    while True:
        while time.strftime('%H:%M:%S') != str(hours)+":"+str(minutes)+":"+str(seconds):
            if GPIO.input(btn) == GPIO.HIGH:
                GPIO.output(pin, GPIO.LOW)
                time.sleep(0.01)
            else:
                GPIO.output(pin, GPIO.HIGH)
                time.sleep(0.01)
 
        GPIO.output(pin, GPIO.LOW)
        time.sleep(2)
        GPIO.output(pin, GPIO.HIGH)
 
 
 
@app.route('/')
def home():
    return render_template('home.html')
 
@app.route('/', methods=['POST'])
def HomePost():
    inputdir = request.form
    print(inputdir)
    hours = inputdir["hours"]
    minutes = inputdir["minutes"]
    seconds = inputdir["seconds"]
    p1.terminate()
    p1=multiprocessing.Process(target = main, args = (hours, minutes, seconds))
    p1.start()
 
    return render_template('home.html')
 
 
 
 
if __name__ == "__main__":
    setup()
    p1 = multiprocessing.Process(target = main, args = (16, 00, 00))
    p1.start()
    app.run(host='0.0.0.0')
Im trying to start the main function on a new process (because it's a loop) with initial values. I want to be able to restart the main function with different arguments which i get as a Webinput. So im trying to kill the process and then restart it with the right Webinputs as the arguments. I also want to be able to change the values that main is using at any time using my webinterface.

The problem is that the process variable p1 is locale so i can't terminate it with p1.terminate() in the HomePost function which is called by flask whenever i submit my inputs. Whenever the HomePost function gets called i get the error: UnboundLocalError: loval variable 'pi' referenced before assignment

How can i kill the process with the HomePost function?


ghp
Posts: 1484
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Python multiprocessing: terminate a process

Tue Jun 30, 2020 6:51 pm

Friendly remark: provide all needed html pages needed to rerun a problem.

Thought a while and think that stopping the process 'main' is a little bit too drastic.
Reworking the code to get updates by a queue could solve the problem.

Code: Select all

def main(pqueue):
    compare_values = None
        
    while True:
        try:
            data = pqueue.get()
            compare_values = data
            hours = data[0]
            minutes = data[1]
            seconds = data[2]
            print("main received data", data)
        except Exception:
            # print ("no data")
            pass
        
        if compare_values is not None:
            if time.strftime('%H:%M:%S') != str(hours)+":"+str(minutes)+":"+str(seconds):
                ....
                ....
A time.sleep(0.01) is possibly too fast and will consume too much cpu. 0.1 sec when time is in seconds will suffice.

This is the start procedure.

Code: Select all

if __name__ == "__main__":
    setup()
    pqueue = multiprocessing.Queue()
    p1 = multiprocessing.Process(target = main, args = (pqueue,) )
    p1.start()
    pqueue.put( (16, 0, 0) )
And in the web form code, use something like

Code: Select all

@app.route('/', methods=['POST'])
def HomePost():
    inputdir = request.form
    
    hour = ...
    minute = ...
    second = ...
    pqueue.put( (hour, minute, second) )
 
    return render_template('home.html')

Return to “Python”