2016-12-16 2 views
-1

У меня есть raspberry pi с кодом python. Время от времени мои устройства не смогут зарегистрироваться. Остальная часть кода на Python продолжает работать отлично, но код здесь завершается. Я не уверен, почему? Если устройства не могут зарегистрироваться, они должны перезагрузиться, но они этого не делают. Другие потоки в файле python продолжают работать правильно.Ошибка в потоке python

class reportStatus(Thread): 
    def run(self): 
     checkInCount = 0 
     while 1: 
      try: 
       if checkInCount < 50: 
        payload = {'d':device,'k':cKey} 
        resp = requests.post(url+'c', json=payload) 
        if resp.status_code == 200: 
         checkInCount = 0 
         time.sleep(1800) #1800 
        else: 
         checkInCount += 1 
         time.sleep(300) # 2.5 min 
       else: 
        os.system("sudo reboot") 
      except: 
       try: 
        checkInCount += 1 
        time.sleep(300) 
       except: 
        pass 

Устройство может работать в течение нескольких дней и недель, и будет проверять в совершенстве через каждые 30 минут, а затем на ровном месте они остановятся. Мои компьютеры linux доступны только для чтения, и компьютер продолжает работать и работать правильно. Моя проблема в этой теме. Я думаю, что они, возможно, не в состоянии получить ответ и эта линия может быть проблема

resp = requests.post(url+'c', json=payload) 

Я не знаю, как решить эту проблему, любая помощь или предложения будут высоко оценены.

Спасибо

+6

Исправить ваши отступы. –

+0

Есть ли у вас трассировка вообще? Я бы не сказал, что запросы - это проблема, так как после этого есть исключение «catch all». –

+0

Вставка для копирования вызвала ошибку отступа, она правильна в файле python. –

ответ

0

A голый except:pass is a very bad idea.

Гораздо лучше было бы, на самом минимуме, журнал исключений:

import traceback 

while True: 
    try: 
    time.sleep(60) 
    except: 
    with open("exceptions.log", "a") as log: 
     log.write("%s: Exception occurred:\n" % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) 
     traceback.print_exc(file=log) 

Затем, когда вы получите исключение, вы получите журнал:

2016-12-20 13:28:55: Exception occurred: 
Traceback (most recent call last): 
    File "./sleepy.py", line 8, in <module> 
    time.sleep(60) 
KeyboardInterrupt 

Это также возможно, что ваш код висит на sudo reboot или requests.post. Вы можете добавить дополнительную регистрацию для устранения неполадок, которые выдают вас, хотя, учитывая, вы видели это сделать перезагружается, я подозреваю, что это requests.post, в этом случае вам нужно добавить timeout (from the linked answer):

import requests 
import eventlet 
eventlet.monkey_patch() 


#... 
resp = None 
with eventlet.Timeout(10): 
    resp = requests.post(url+'c', json=payload) 
if resp: 
    # your code 
+0

Я уверен, что код не висит на перезагрузке sudo. Отличный ответ! Спасибо! Я уверен, что requsts.post не получает ответа изредка и ждет навсегда. –

0

Ваш код в основном игнорирует все исключения. В Python это считается плохой.

Единственная причина, по которой я могу думать о поведении, которое вы видите, заключается в том, что после того, как checkInCount достигает 50, sudo reboot создает исключение, которое затем игнорируется вашей программой, сохраняя эту нить застрявшей в бесконечном цикле.

Если вы хотите увидеть, что на самом деле происходит, добавьте print или loggging.info заявления ко всем различным ветвям вашего кода.

В качестве альтернативы, удалите предложение try-except одеяла или замените его на что-то конкретное, например. except requests.exceptions.RequestException

0

Из-за ответы я смог прийти к решению. Я понял, что запросы имеют встроенную функцию тайм-аута. Тайм-аут никогда не произойдет, если таймаут не указан в качестве параметра.
вот мое решение:

resp = requests.post(url+'c', json=payload, timeout=45) 

Вы можете сказать запросы прекратить ожидание ответа после заданного количество секунд с помощью параметра тайм-аута. Почти весь код должен использовать этот параметр почти во всех запросах.Несоблюдение этого Это может привести к вашей программе зависнуть

ответы, представленные TemporalWolf и другие помогли мне много. Спасибо всем, что помогло.

+0

Встроенный тайм-аут помогает, но не предотвращает зависание - это максимальная ожидание * между * серверами, а не максимальное время возврата вызова. – TemporalWolf

+0

ОК. Я буду использовать eventlet. –