2016-04-20 145 views
0

我正在写一个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秒,实际上停止计数。那不会削减它。任何想法发生了什么?

+0

'while self.counterOn == 1:'会比'true'更有意义,我想。即使那样,如果没有外部干扰,你可能无法做到自己想做的事。您的循环可以从Web界面可以写入的文件中读取并以此方式确定其操作过程。 – jDo

+0

这实际上不是一个坏主意。我并不是很熟悉python(或者真的是编程),所以我真的只是为了“让它工作”而采取一种方法,但我想尽可能地学习“正确”的做法。我也会有一些温度控制功能,所以也许外部文件是最干净的方式。我会看看其他人是否有想法,但谢谢! – thekevster08

+0

凉爽。我自己使用了这样的外部文件;例如对于一个调度系统,管理cron作业而无需实际编辑crontab,做传感器读数,控制继电器等。它工作正常。 – jDo

回答

0

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

我都会主动与互斥的应该是能够提供一个暂停/恢复功能的问题(一个标准的并发控制技术):

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