2016-04-20 143 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