python 即使有异常处理也会挂起

python hangs even with exception handling

我有一个 raspberry PI 连接到 MCP3008 ADC,它正在测量热敏电阻两端的模拟电压。我正在使用 gpiozero python 库在 PI 和 ADC 之间进行通信。我下面的代码运行了几分钟然后吐出一个错误,然后挂在函数 get_temp_percent 上。该函数 returns 来自 ADC 的五次测量的平均值。我正在使用 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!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

看来您对 gpiozero 的调用在幕后做了很多工作。 处理您的异常时,库正在尝试清理并卡住。

我快速浏览了库的文档,看起来您可以保留引脚以便 re-use 它们。

例如

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()
   ...