Python从外部启停运行中函数:树莓派SenseHat进程重启报错求解
问题原因
Python multiprocessing.Process 实例为一次性生命周期设计,实例完成运行或被终止后,不允许再次调用 start() 方法启动,这是触发报错的根本原因。
修复方案
每次需要启动显示逻辑时,重新创建新的 Process 实例即可,同时新增进程运行状态判断,避免重复启动已运行的进程触发异常。
附加优化点:
- 将 SenseHat 实例初始化移入显示函数内部,避免跨进程操作硬件引发偶发故障
- 终止进程后调用
join()等待资源完全释放,避免产生僵尸进程 - 新增多进程标准入口判断,兼容不同系统的多进程运行规则
修改后代码
from sense_hat import SenseHat from gpiozero import CPUTemperature import time from multiprocessing import Process def main_display(): # 把sense初始化放到子进程内部,避免跨进程硬件冲突 sense = SenseHat() w = (50, 50, 50) display = [ w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w ] cpu_array = [] while True: # 校准温度 temp = sense.get_temperature() cpu = CPUTemperature() cpu_temp = cpu.temperature if len(cpu_array) < 100: cpu_array.append(cpu_temp) else: cpu_array.append(cpu_temp) cpu_array.pop(0) av_cpu_temp = sum(cpu_array) / len(cpu_array) temp_calibrated = temp - ((av_cpu_temp - temp) * 1.6) pres = sense.get_pressure() hum = sense.get_humidity() # 温度列渲染 temp_list = [56, 57, 48, 49, 40, 41, 32, 33, 24, 25, 16, 17, 8, 9, 0, 1] temp_color = [(0, 0, 255), (20, 0, 235), (40, 0, 215), (70, 0, 185), (100, 0, 155), (120, 0, 135), (140, 0, 115), (160, 0, 95), (170, 0, 85), (180, 0, 75), (190, 0, 65), (200, 0, 55), (210, 0, 45), (220, 0, 35), (230, 0, 25), (255, 0, 0)] i = 0 target_temp = 0 while i < len(temp_list): display[temp_list[i]] = temp_color[i] if temp_calibrated >= target_temp else w i += 1 target_temp += 3 # 气压列渲染 pres_list = [59, 60, 51, 52, 43, 44, 35, 36, 27, 28, 19, 20, 11, 12, 3, 4] pres_color = [(255,255,153), (255, 243, 157), (255,232,162), (255,209,172), (255, 197, 176), (255,185,181), (255,162,190), (255,139,199), (255,116,209), (255,93,218), (255, 81, 222), (255,70,227), (255,46,236), (255,23,246), (255, 11, 250), (255,0,255)] j = 0 target_pres = 930 while j < len(pres_list): display[pres_list[j]] = pres_color[j] if pres >= target_pres else w j += 1 target_pres += 10 # 湿度列渲染 hum_list = [62, 63, 54, 55, 46, 47, 38, 39, 30, 31, 22, 23, 14, 15, 6, 7] hum_color = [(0,255,0), (0, 243, 11), (0,232,23), (0,209,46), (0,185,70), (0,162,93), (0, 150, 104), (0,139,116), (0,116,139), (0,93,162), (0, 81, 173), (0,70,185), (0,46,209), (0,23,232), (0, 11, 244), (0,0,255)] k = 0 target_hum = 0 while k < len(hum_list): display[hum_list[k]] = hum_color[k] if hum >= target_hum else w k += 1 target_hum += 6.25 sense.set_pixels(display) time.sleep(1) if __name__ == "__main__": # 主进程保留sense实例用于摇杆检测 sense = SenseHat() current_process = None # 启动时默认运行显示 current_process = Process(target=main_display) current_process.start() while True: for event in sense.stick.get_events(): if event.action == "pressed": if event.direction == "up": # 仅无运行中进程时启动新进程 if current_process is None or not current_process.is_alive(): current_process = Process(target=main_display) current_process.start() elif event.direction == "down": # 仅存在运行中进程时执行终止 if current_process is not None and current_process.is_alive(): current_process.terminate() current_process.join() current_process = None sense.clear() time.sleep(0.1)
内容的提问来源于stack exchange,提问作者Wallaby3
相关产品推荐
相关产品推荐

