我正在写一个Web服务器来记录温度。用户点击Web界面上的“收集数据”,然后触发烧瓶功能运行“收集温度”功能,该功能只是无限期地收集温度数据。然后,我希望用户能够点击一个“停止数据收集”按钮,在停止循环时停止收集温度功能。Python - 退出while循环外部
的问题(我的理解至少)归结为类似下面的代码:
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循环中。我尝试了线程只发现你不能暂停或停止线程。我在看这个完全错误的,还是像尝试/除外那么简单?
编辑:
外部文件的想法是伟大的。我在解析文本文件的时候遇到了一些麻烦,并且在整个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()上。它永远不会返回数据,所以当我试图停止数据收集时,flask脚本将不会解释停止命令。
所以我转向互斥体。这正是我认为可以通过线程发布的功能。它似乎工作正常,除了第二次停止收集通常会有很长的延迟。
@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秒,实际上停止计数。那不会削减它。任何想法发生了什么?
'while self.counterOn == 1:'会比'true'更有意义,我想。即使那样,如果没有外部干扰,你可能无法做到自己想做的事。您的循环可以从Web界面可以写入的文件中读取并以此方式确定其操作过程。 – jDo
这实际上不是一个坏主意。我并不是很熟悉python(或者真的是编程),所以我真的只是为了“让它工作”而采取一种方法,但我想尽可能地学习“正确”的做法。我也会有一些温度控制功能,所以也许外部文件是最干净的方式。我会看看其他人是否有想法,但谢谢! – thekevster08
凉爽。我自己使用了这样的外部文件;例如对于一个调度系统,管理cron作业而无需实际编辑crontab,做传感器读数,控制继电器等。它工作正常。 – jDo