python зависает даже при обработке исключений

У меня есть Raspberry PI, подключенный к АЦП MCP3008, который измеряет аналоговое напряжение на термисторе. Я использую библиотеку Python gpiozero для связи между PI и ADC. Мой код ниже работает несколько минут, а затем выдает ошибку, а затем зависает на функции get_temp_percent. Эта функция возвращает среднее значение пяти измерений от АЦП. Я использую Signal для создания исключения через 1 секунду ожидания, чтобы попытаться преодолеть зависание, но оно просто выдает ошибку и все равно зависает. Похоже, в моем заявлении except ничего не читается. Почему я не избегаю зависания кода?

import time
from gpiozero import MCP3008
from math import log
import pymysql.cursors
from datetime import datetime as dt
import signal 
import os


def handler(signum, frame):
    print('Signal handler called with signal', signum, frame)
    raise Exception("Something went wrong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")   


def get_temp_percent(pos=0):
    x=[]
    for i in range(0,5):
        while True:
            try:
                signal.signal(signal.SIGALRM, handler)
                signal.alarm(1)
                adc = MCP3008(pos)
                x.append(adc.value)
                #adc.close()
            except Exception as inst:
                print('get_temp_percent {}'.format(inst) )
                signal.alarm(0)
                continue
            break
        signal.alarm(0)
        time.sleep(.1)
    return round(sum(x)/len(x),5)


def write_date(temp0):
    <writes temp0 to mysql db >        

# Connect to the database
connection = pymysql.connect(host='', user='', password='', db='',cursorclass = pymysql.cursors.DictCursor)

while True:        
    temp_percent = get_temp_percent()
    print('Temp Percent = {}'.format(temp_percent) )

    <some function that do some arithmetic to go temp_percent to temp0>

    write_date(temp0)
    print('Data Written')

    time.sleep(1)
    print('Sleep time over')
    print('')

Функция get_temp_percent вызывает проблему ниже

Signal handler called with signal 14 <frame object at 0x76274800>
Exception ignored in: <bound method SharedMixin.__del__ of SPI(closed)>
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gpiozero/mixins.py", line 137, in __del__
    super(SharedMixin, self).__del__()
  File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 122, in __del__
    self.close()
  File "/usr/lib/python3/dist-packages/gpiozero/devices.py", line 82, in close
    old_close()
  File "/usr/lib/python3/dist-packages/gpiozero/pins/local.py", line 102, in close
    self.pin_factory.release_all(self)
  File "/usr/lib/python3/dist-packages/gpiozero/pins/__init__.py", line 85, in release_all
    with self._res_lock:
  File "/home/pi/Desktop/testing exceptions.py", line 13, in handler
    raise Exception("Something went wrong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
Exception: Something went wrong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

person Aryeh Gielchinsky    schedule 19.03.2018    source источник
comment
У тебя в итоге заработало?   -  person Hitobat    schedule 05.04.2018
comment
да, я только что принял ваш ответ, извините за задержку. Большое спасибо. Что смущает, так это то, почему сигнал и тревога не сбрасывали ошибку?   -  person Aryeh Gielchinsky    schedule 08.04.2018
comment
Сигнал и тревога обычно просто очищают стек. Для приложения, не касающегося кучи, это нормально, но любое выделение памяти или взаимодействие с реальным оборудованием может быть прервано и привести к несогласованному состоянию. Вот, вероятно, что здесь произошло; первые несколько раз будильник срабатывал нормально, но в конце концов вам не повезло, и он зависает.   -  person Hitobat    schedule 09.04.2018


Ответы (1)


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

Я быстро просмотрел документы для библиотеки, и похоже, что вы сможете сохранить контакты, чтобы использовать их повторно.

e.g.

import ...

adcs = {}

def get_adc_value(pos):
    if pos not in adcs:
        adcs[pos] = MCP3008(pos)
    return adcs[pos].value

def get_temp_percent(pos=0):
    x = []
    for i in range(0, 5):
        x.append(get_adc_value(pos))
        time.sleep(.1)
    return round(sum(x)/len(x),5)

while True:
   temp_percent = get_temp_percent()
   ...
person Hitobat    schedule 19.03.2018
comment
Кажется, это помогло. Я собираюсь дать ему поработать в течение дня и посмотреть, вылетит ли он или зависнет, а затем отчитаюсь. Благодарность - person Aryeh Gielchinsky; 20.03.2018