Reputation: 302
I'm making a flask application, and when the user presses a button I want for a thread to pause until the button is pressed again, and i'm planning to do this with a flag being set off. The thread can read the initial value of the flag, but when the user presses the button and the value is changed, the value remains false in the thread. It can read it successfully, but it just can't change it. I've tried making it global but it still has no effect. Here is the source -
web = False
@app.route("/")
def bg_func():
print('Thread test')
while True:
if web == False :
if Facial_Check.run() == True:
face_detected = True
t = Thread(target=bg_func)
t.start()
@app.route("/<changePin>/<action>")
def action(changePin, action):
changePin = int(changePin)
deviceName = pins[changePin]['name']
global web
if action == "on":
GPIO.output(changePin, GPIO.HIGH)
time.sleep(1)
GPIO.output(changePin, GPIO.LOW)
web = True
current_status = True
message = "Turned computer on."
if action == "off":
GPIO.output(changePin, GPIO.HIGH)
time.sleep(1)
GPIO.output(changePin, GPIO.LOW)
web = False
current_status = False
face_detected = False
message = "Turned computer off."
for pin in pins:
pins[pin]['state'] = GPIO.input(pin)
return render_template('index.html', Status=current_status)
Upvotes: 2
Views: 98
Reputation: 9364
You should use thread-specific features to be able share data between threads.
You may use current_thread
for these purposes:
from flask import Flask
from time import sleep
from threading import Thread, current_thread
app = Flask(__name__)
web = current_thread()
def bg_func():
i = 0
while i < 100:
i += 1
sleep(2)
print('web is', getattr(web, 'web', None))
@app.route("/<my_web>")
def index(my_web = '0'):
before = getattr(web, 'web', None)
if my_web == '1':
setattr(web, 'web', True)
else:
setattr(web, 'web', False)
after = getattr(web, 'web', None)
return f"set {before} to {after}"
if __name__ == '__main__':
setattr(web, 'web', False)
t = Thread(target=bg_func)
t.start()
app.run(host='127.0.0.1', port=8080)
browser output will be:
set False to True
when access http://127.0.0.1:8080/1
first time
terminal output will be:
web is False
web is False
web is True
web is True
...
I added socket listeners as in your example:
from flask import Flask
from time import sleep
from threading import Thread, current_thread
from flask_socketio import SocketIO
def bg_func():
print('Thread test')
while True:
sleep(1)
print('web is ' + str(web.web))
app = Flask(__name__)
web = current_thread()
socketio = SocketIO(app)
setattr(web, 'web', None)
@app.route("/")
def action():
return 'web is ' + str(web.web)
@socketio.on('connect')
def connect():
setattr(web, 'web', True)
print('Client connected to server ')
@socketio.on('disconnect')
def disconnect():
setattr(web, 'web', False)
print('Client disconnected from server ')
if __name__ == "__main__":
t = Thread(target=bg_func)
t.start()
socketio.run(app, host='127.0.0.1', port=7878, debug=False)
import socketio
sio = socketio.Client()
sio.connect('http://127.0.0.1:7878')
When I using client the output at server side is looking like:
...
web is None
web is None
...
Client connected to server
web is True
web is True
...
Client disconnected from server
web is False
web is False
...
as you can see here is debug=False
in my code. That is because of Flask run two app
threads in DEBUG
mode.
So first of web
is controlled by you, second one is never changing and always will show None
(if you change debug to True
).
Upvotes: 2