Python - 外部循环退出

时间:2016-04-20 23:57:23

标签: python flask

我正在编写一个可以记录温度的Web服务器。用户点击"收集数据"在Web界面上,然后触发烧瓶功能以运行"收集温度"只是无限收集温度数据的功能。然后我希望能够让用户点击"停止数据收集"循环时会停止收集温度功能的按钮。

问题(至少我的理解)归结为以下代码:

class myClass:
    counterOn = 0
    num = 0

    def __init__(self):
        self.num = 0

    def setCounterOn(self, value):
        self.counterOn = value

    def printCounterOn(self):
        print self.counterOn

    def count(self):
        while True:
            if self.counterOn == 1:
                self.num += 1
                print self.num
                time.sleep(1)

然后是服务器文件:

myCounter = myClass.myClass()
myCounter.setCounterOn(1)
myCounter.count()
time.sleep(5)
myCounter.setCounterOn(0)

理想情况下,我希望服务器文件创建一个计数器对象,然后在外部打开和关闭计数器功能。因为它现在起作用,它停留在while循环中。我试过线程只是发现你不能暂停或停止一个线程。我是在看这个完全错误的,还是像try / except一样简单?

修改

外部文件的想法很棒。我在查看文本文件时遇到了一些问题,并且在ConfigParsers中偶然发现了读取.ini文件。我想我会这样做,因为最终我想要一个控制温度的PID控制器,能够在外部存储配置会很棒。

我实现了一个永远循环的while循环,只有在看到配置为收集的配置文件时才会记录。问题是,在我的烧瓶文件中,我会运行

@app.route('/startCollection', methods=['POST'])
def startCollectData():
    print "collectPressed"
    config.read('congif.ini')
    config.set('main', 'counterOn', '1')
    with open('config.ini', 'w') as f:
        config.write(f)
    C.count()
    return "collect data pressed"

@app.route('/stopCollection', methods=['POST'])
def stopCollectData():
    print "stop hit"
    config.read('config.ini')
    config.set('main', 'counterOn', '0')
    with open('config.ini', 'w') as f:
        config.write(f)
    C.count()    
    return "stop pressed"

def count(self):
    while True:
        self.config.read('config.ini')
        print self.num
        time.sleep(1)
        if self.config.get('main', 'counterOn') == '1':
            self.num += 1

根据我的观察,startDataCollection被卡在count()上。它永远不会返回数据,所以当我试图停止数据收集时,烧瓶脚本不会在那里解释停止命令。

所以我转向互斥锁。这正是我认为带有线程的开箱即用的功能。它似乎工作正常,除了第二次停止收集通常会有很长的延迟。

@app.route('/')
def main():
    print "MYLOG - asdf"
    cls.start()
    cls.pause()
    return render_template('index.html')

@app.route('/startCollection', methods=['POST'])
def startCollectData():
    print "collectPressed"
    cls.unpause()    
    return "collect data pressed"

@app.route('/stopCollection', methods=['POST'])
def stopCollectData():
    print "stop hit"    
    cls.pause()
    return "collect data pressed"
如果我点击开始,停止,开始,然后停止,

会产生以下输出:

collectPressed
1
10.240.0.75 - - [22/Apr/2016 15:58:42] "POST /startCollection HTTP/1.1" 200    -
2
3
4
5
6
7
8
9
stop hit
10.240.0.207 - - [22/Apr/2016 15:58:51] "POST /stopCollection HTTP/1.1" 200 -
collectPressed
10
10.240.0.166 - - [22/Apr/2016 15:58:57] "POST /startCollection HTTP/1.1" 200 -
11
12
13
14
15
16
stop hit
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
10.240.0.75 - - [22/Apr/2016 15:59:24] "POST /stopCollection HTTP/1.1" 200 -

所以我点击停止,然后收集20秒,然后它最终停止。我的收集点将相隔5分钟,所以它不是什么大问题,但只是好奇。

import threading
import time

class myThread(threading.Thread):
num = 0

def __init__(self, threadID, name, counter):
    threading.Thread.__init__(self)
    self.threadID = threadID
    self.name = name
    self.counter = counter
    self.mutex = threading.Lock()
    self.paused = False

def pause(self):
    if(not self.paused):
        self.mutex.acquire()
        self.paused = True

def unpause(self):
    self.mutex.release()
    self.paused = False

def run(self):
    print "starting" + self.name
    while True:
        self.mutex.acquire()
        self.num += 1
        print self.num
        time.sleep(1)
        self.mutex.release()

无论如何,谢谢你的帮助。我已经被困在如何处理这个问题大约4个月了,最终在它上面取得了一些进展!

编辑2 实际上,只是再次运行它需要100秒才能实际停止计数。多数民众赞成不会削减它。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我会尝试再次使用线程。事实是你有一个需要运行的计算,而另一个指令序列(即GUI逻辑)也需要执行。

我会用mutex(标准并发控制技术)解决这个问题,它应该能够提供暂停/取消暂停功能:

import time
import threading

class myClass(threading.Thread):
    num = 0

    def __init__(self):
        super(myClass, self).__init__()
        self.num = 0
        self.mutex = threading.Lock()
        self.paused = False

    def pause(self):
        if(not self.paused):
            self.mutex.acquire()
            self.paused = True

    def unpause(self):
        self.mutex.release()
        self.paused = False

    def run(self):
        while True:
            self.mutex.acquire()
            self.num += 1
            print self.num
            time.sleep(1)
            self.mutex.release()

cls = myClass()
cls.start()

time.sleep(10)
cls.pause()
time.sleep(2)
cls.unpause()
time.sleep(2)

这应该输出:(或类似的东西)

1
2
3
4
5
6
7
8
9
10
(wait)
11
12