我正在编写一个可以记录温度的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秒才能实际停止计数。多数民众赞成不会削减它。有什么想法吗?
答案 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