PiFace

#python #raspberry-pi

#python #raspberry-pi

Вопрос:

У меня есть плата PiFace, установленная на моем Raspberry Pi, и я хочу завершить свою программу на Python, когда я нажимаю кнопку 3. Поэтому я подключаю прослушиватель прерываний к этой кнопке и вызываю 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
  

So counter увеличивается при каждом нажатии, но loop просто не принимает мой вызов stop. Кто-нибудь может сказать мне, как остановить цикл? Заранее спасибо

Комментарии:

1. вы уверены, что asyncio должен запускаться на raspberry-pi? (возможно, это не raspberry-py по какой-то причине : D)

2. @vlad-ardelean Я полагаю, что да. Почему бы и нет? Тем временем я попробую обходной путь с Barrier объектом.

Ответ №1:

Я предполагаю, что у вас запущены некоторые сопрограммы и вы выполняете некоторую работу, потому что в этом фрагменте нет необходимости в asyncio, он просто не используется для блокировки…

Тем не менее, я совершенно уверен, что у вас есть проблема с потоками.

Смотрю на GitHub в модулях:

 piface.InputEventListener()
  

получает из pifacecommon.прерывает.PortEventListener

 class InputEventListener(pifacecommon.interrupts.PortEventListener):
  

на github pifacedigitalio

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
  

github pifacecommon

кажется, выполняется в другом потоке и вызывает вас обратно. Очевидно, что остановка не достигает asyncio.цикл в основном потоке.


Согласен, пока?

В идеале вы должны использовать либо потоковое, либо асинхронное программирование в одном потоке.

Тем не менее, я ожидаю, что передача ссылки на цикл вместо ее глобального использования сработает: def onQuit (цикл):

 listener.register(QUIT_DETECT, piface.IODIR_FALLING_EDGE, onQuit(loop))
  

или
из functools частично импортируется
listener.register(ЗАВЕРШАЕТ ОБНАРУЖЕНИЕ, piface.IODIR_FALLING_EDGE, частичное (завершение, цикл))


Вы пытались повторно запустить цикл вместо глобального использования в onQuit? asyncio.get_event_loop()

Веселись, Дэнни