Python线程,全局变量和奇怪的行为

时间:2016-06-10 21:25:58

标签: python multithreading flask global-variables

我正在使用Python的Flask应用程序为我的Raspberry Pi打开/关闭我的车库门,同时监控门是打开还是关闭。所以我决定运行一个只检查车库门传感器的线程,然后设置一个全局变量True / False(打开或关闭)。当传感器状态发生任何变化时,线程还会将这些项写入日志文件。对于调试,我修改了代码以检查文本文件而不是实际的GPIO。以下是我的代码中的相关摘录:

from flask import Flask, render_template
import threading
import time
import datetime
import os

app = Flask(__name__)

door_state = False # Global state of the door open / close sensor

def checkdoorstate():
    global door_state

    while True:
        file = open("sensor.txt", "r")
        sensorstatus = file.read(5)
        file.close()
        if (sensorstatus == "True" and door_state != True):
            door_state = True
            time.sleep(2)
            now = str(datetime.datetime.now())
            doorhistory = open("events.log", "a")
            doorhistory.write(now + " Door_Opened\n")
            doorhistory.close()
        if (sensorstatus == "False" and door_state != False):
            door_state = False
            time.sleep(2)
            now = str(datetime.datetime.now())
            doorhistory = open("events.log", "a")
            doorhistory.write(now + " Door_Closed\n")
            doorhistory.close()

以下是代码的烧瓶部分:

@app.route('/')
def index():
    global door_state
    temp = checkcputemp()

    door_history = []
    events = 0
    readeventhistory(door_history, events)

    return render_template('index.html', state=door_state, temp=temp, events=events, door_history=door_history)

@app.route('/button')
def button():
    global door_state
    # Insert code to push button here
    #RPi.GPIO.output(23, 0)     #Turn on Relay
    time.sleep(0.5)         #Wait for 0.5s
    #RPi.GPIO.output(23, 1) #Turn off Relay

    now = str(datetime.datetime.now())
    doorhistory = open("events.log", "a")
    doorhistory.write(now + " Button_Pressed\n")
    doorhistory.close()

    door_history = []
    events = 0
    readeventhistory(door_history, events)

    temp = checkcputemp()
    return render_template('index.html', state=door_state, temp=temp, events=events, door_history=door_history)

这是我启动线程和烧瓶app的部分:

door_sensor_thread = threading.Thread(target=checkdoorstate)
door_sensor_thread.start()

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=80)

但是,我发现当我实现它时,日志文件有时会为每个事件显示两个条目!这是日志文件的样子:

2016-06-10 13:26:33.070493 Door_Closed
2016-06-10 13:26:33.073504 Door_Closed
2016-06-10 13:26:35.786584 Door_Opened
2016-06-10 13:26:35.787585 Door_Opened
2016-06-10 13:26:39.400829 Door_Closed
2016-06-10 13:26:39.402847 Door_Closed
2016-06-10 13:26:45.225965 Door_Opened
2016-06-10 13:26:48.756923 Door_Closed
2016-06-10 13:44:34.309371 Door_Opened
2016-06-10 13:44:34.313374 Door_Opened
2016-06-10 13:44:38.641659 Door_Closed
2016-06-10 13:44:38.642577 Door_Closed
2016-06-10 13:44:41.100819 Door_Opened
2016-06-10 13:44:41.105739 Door_Opened
2016-06-10 13:44:44.098574 Door_Closed
2016-06-10 13:44:44.099588 Door_Closed
2016-06-10 13:44:46.716084 Door_Opened
2016-06-10 13:44:46.718087 Door_Opened
2016-06-10 13:44:49.689527 Door_Closed
2016-06-10 13:44:58.031547 Door_Opened
2016-06-10 13:45:02.450425 Door_Closed
2016-06-10 13:45:13.070788 Door_Opened
2016-06-10 13:45:17.375065 Door_Closed

糟糕!我试图实现锁定,但我也不确定我是否也正确地执行了此操作。这是一个奇怪的竞争条件或时间事情,线程写入全局变量的速度很慢?

我只有一个帖子。脚本的其他任何部分都没有写入此全局变量,只有读取在此线程外部完成。

提前感谢您的帮助!

0 个答案:

没有答案