2016-04-20 3 views
0

Я пишу веб-сервер, который регистрирует температуры. Пользователь нажимает «собирать данные» на веб-интерфейсе, который затем запускает функцию колбы для запуска функции «собирать температуру», которая просто собирает данные о температуре на неопределенный срок. Затем я хочу, чтобы пользователь мог нажать кнопку «остановить сбор данных», которая остановила бы функцию температуры закрытия во время цикла.Python - Выход из цикла во внешнем виде

Проблема (мое понимание, по крайней мере) сводится к тому, что-то вроде следующего кода:

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?

Edit:

Внешний идея файл велик. У меня возникли проблемы с синтаксическим разбором текстового файла по моим функциям, и я столкнулся со спонтанностью через ConfigParsers для чтения файлов .ini. Я думаю, что я пойду так, потому что в конце концов я хочу, чтобы ПИД-регулятор контролировал температуру, и будет здорово хранить конфигурации извне.

Я реализовал только цикл 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 был застрять на счете(). Он никогда не будет возвращать данные, поэтому, когда я попытаюсь остановить сбор данных, скрипт флака не будет интерпретировать команду остановки.

Итак, я перешел к мьютексу. Это именно те функциональности, которые, как я думал, выходят из коробки с потоками. Кажется, что он работает нормально, за исключением, как правило, очень большой задержки во второй раз, когда я останавливаю сбор.

@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:' будет иметь больше смысла, чем 'while True', я думаю. Даже тогда вы, возможно, не сможете делать то, что хотите, без какого-либо внешнего вмешательства. Ваша петля может читать из файла, который может написать веб-интерфейс, и определить способ его действия. – 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 
Смежные вопросы