简体   繁体   中英

Non-blocking infinite loop

I have a Raspberry pi with a Sense hat. I've made a binary clock that I want to display and keep updated on the Sense hat's display. However, I want the ability to toggle the clock on and off with joystick middle. Everything's working fine, apart from my clock's update-loop blocking any new input once it's started.

from sense_hat import SenseHat
from signal import pause

def show_clock():
    # clock-logic

def pushed_middle(event):
    while 1:
        show_clock()

sense = SenseHat()

sense.stick.direction_middle = pushed_middle
pause

I've been thinking about how to solve this. How to allow the script/clock to keep running and still accept new actions from the joystick. But once the while-loop starts, I'm stuck. I'm not sure what to google for. I've started looking into async/await, but that seem to be a Python 3.5+ feature, and my pi only has 2.7.9/3.4.2(I just sudo apt-get update/upgrade -ed). I've also tried moving the loop around in the program, but it's blocking everything no matter where I place it.

  • Is it a non-blocking (infinite) loop I'm looking for?
  • Is this what a game-/event-loop is?
  • Can I solve this with out using multiple threads(just curious, not a limitation if it's a must)?
  • Is this a general problem in "designing" infinite loops?
  • Can I approach this as a (reverse?) race condition? I was thinking about maybe using a semaphore as some kind of tool to not block, but I'm not sure.

What you need is multithreading. Here you can find a good explanation with example.

How to use threading in Python?

I solved it by using a global variable:

from sense_hat import SenseHat
from signal import pause

def show_clock():
    global clock_is_on

    while clock_is_on:  # clock-loop
        # clock-logic
        # ...

        events = sense.stick.get_events()

        for event in events:
            if event.direction == "middle" and event.action == "pressed":
              clock_is_on = False

        time.sleep(1) # only need to update clock once every second

def pushed_middle(event):
    if not clock_is_on:
        clock_is_on = True
        show_clock()

sense = SenseHat()

clock_is_on = False

sense.stick.direction_middle = pushed_middle
pause()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM