我有一个 PiFace 板堆叠在我的 Raspberry Pi 上,并且想要在按下按钮 3 时退出我的 python 程序。因此,我将一个中断监听器附加到该按钮并在回调中调用loop.stop(),但我的循环赢了不要停止。就好像我的命令被忽略了。
我的代码:
#!/usr/bin/python3
import pifacedigitalio as piface
import asyncio
import time
QUIT_DETECT = 3
loop = asyncio.get_event_loop()
counter = 0
def onQuit(event):
# Doesn't stop
global loop
loop.stop()
print(loop)
# Does change
global counter
counter += 1
print(counter)
piface.init()
listener = piface.InputEventListener()
listener.register(QUIT_DETECT, piface.IODIR_FALLING_EDGE, onQuit)
listener.activate()
loop.run_forever()
loop.close()
listener.deactivate()
piface.deinit()
输出为:
<_UnixSelectorEventLoop running=True closed=False debug=False>
1
<_UnixSelectorEventLoop running=True closed=False debug=False>
2
<_UnixSelectorEventLoop running=True closed=False debug=False>
3
<_UnixSelectorEventLoop running=True closed=False debug=False>
4
因此每次按下时计数器
都会增加,但loop
不会接受我的停止调用。谁能告诉我如何停止循环?提前致谢
最佳答案
我猜你有一些协程正在运行并做了一些工作,因为在这个片段中不需要 asyncio,它只是被误用于阻塞......
尽管如此,我很确定您遇到了线程问题。
在模块中查看 gitHub:
piface.InputEventListener()
从 pifacecommon.interrupts.PortEventListener 驱动
class InputEventListener(pifacecommon.interrupts.PortEventListener):
PortEventListener 使用线程和多处理
import threading
import multiprocessing
[....]
class PortEventListener(object):
"""Listens for port events and calls the registered functions.
>>> def print_flag(event):
... print(event.interrupt_flag)
...
>>> port = pifacecommon.mcp23s17.GPIOA
>>> listener = pifacecommon.interrupts.PortEventListener(port)
>>> listener.register(0, pifacecommon.interrupts.IODIR_ON, print_flag)
>>> listener.activate()
"""
TERMINATE_SIGNAL = "astalavista"
def __init__(self, port, chip, return_after_kbdint=True, daemon=False):
self.port = port
self.chip = chip
self.pin_function_maps = list()
self.event_queue = EventQueue(self.pin_function_maps)
self.detector = multiprocessing.Process(
target=watch_port_events,
args=(
self.port,
self.chip,
self.pin_function_maps,
self.event_queue,
return_after_kbdint))
self.detector.daemon = daemon
self.dispatcher = threading.Thread(
target=handle_events,
args=(
self.pin_function_maps,
self.event_queue,
_event_matches_pin_function_map,
PortEventListener.TERMINATE_SIGNAL))
self.dispatcher.daemon = daemon
似乎在不同的线程中运行并给您回电。显然停止没有到达主线程中的asyncio.loop。
<小时/>到目前为止,同意吗?
理想情况下,您应该在一个线程中使用线程或异步编程。
尽管如此,我希望它能够移交循环引用,而不是全局使用它: def onQuit(循环):
listener.register(QUIT_DETECT, piface.IODIR_FALLING_EDGE, onQuit(loop))
或者 从 functools 导入部分 Listener.register(QUIT_DETECT,piface.IODIR_FALLING_EDGE,部分(onQuit,循环))
<小时/>您是否尝试过重新获取循环而不是 onQuit 中的全局使用? asyncio.get_event_loop()
玩得开心 丹尼
关于python - PiFace 和异步 : loop won't stop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40202699/