Efficiency of infinite loop to service GPIO

python, raspberry-pi, real-time

Solution

Yes, doing `while True: pass` will burn 100% of your CPU (or as close to it as possible) doing nothing.

From what I understand (hopefully this is documented somewhere), the RPi.GPIO module spawns a background thread that waits on the GPIO and calls your `callback` function for each event. So your main thread really has nothing to do. If you want this to run as a service, make it `sleep` for long periods of time. If you want to run it interactively (in which case you probably want it easier to cancel), `sleep` for shorter periods of time, maybe 0.5 seconds, and add some way to exit the loop.

It would be even nicer if you could do the GPIO `select` in the main thread, or get a handle to the GPIO background thread that you can just `join`, either of which would burn no CPU at all. However, the module doesn't seem to be designed in a way to make that easy.

However, looking at the source, there is a `wait_for_edge` method. Presumably you could loop around `GPIO.wait_for_edge` instead of setting a callback. But without the documentation, and without a device to test for myself, I'm not sure I'd want to recommend this to a novice.

Meanwhile:

Also what happens if the CPU is busy doing something else and a GPIO i/p changes? Does the GPIO event get stored somewhere so it is eventually serviced, or does it just get lost?

Well, while your thread isn't doing anything, the GPIO background thread seems to be waiting on `select`, and `select` won't let it miss events. (Based on the name, that `wait_for_edge` function sounds like it might be edge-triggered rather than level-triggered, however, which is part of the reason I'm wary of recommending it.)

Problem

I'm using Python on Raspbian (a type of linux) on the Raspberry Pi (an embedded processor board) to monitor GPIO inputs. See simplified version of my code below. I have an infinite loop in the python script waiting for something to happen on a GPIO i/p. Is this the correct way to do it? I.e. does this mean that the CPU is running at full whack just going round this loop, leaving no CPU cycles for other stuff? Especially as I need to be running other things in parallel (e.g. the browser). Also what happens if the CPU is busy doing something else and a GPIO i/p changes? Does the GPIO event get stored somewhere so it is eventually serviced, or does it just get lost? Is there a better way of doing this? (For your answers, please note that I'm new to linux, and v. new to python and real-time programming) ``` #!/usr/bin/python import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP) def ButtonHandler(channel): print "Button pressed " + str(channel) # do stuff here GPIO.add_event_detect(16, GPIO.FALLING, callback=ButtonHandler, bouncetime=200) while True: pass ```

Original source

Related problems