Event Loops
Event loops are one approach to concurrent programming that rely on cooperative scheduling.
The way I like to imagine event loops is a while loop slowly processing small pieces of functions, one after the other. That doesn't quite cover the full complexity of an event loop, of course, but does get me very far along the way.
A slightly more traditional way to explain an event loop is a loop that processes a queue full of messages representing some computation – which is definitely closer to the actual implementation.
One of the more interesting parts of this is that a function must choose to relinquish control. Sometimes, it's not even very explicit, such as in Javascript.
The other is that all the interesting things happen outside the event loop: particularly the implementation of whatever is driving the event loop in the first place.
Event loops generally rely on select
, epoll
and similar mechanisms to
trigger the loop: which basically means that the kernel acts as the
out-of-band mechanism to control the process.
Examples of event loops in production
Python's asyncio
Python has a custom event loop implementation, which is something I've spent quite a lot of time investigating.
Node's libuv
libuv is the event loop that backs Node, but is also usable in other systems. It's also installable in Python using uvloop with a single line.
Android's MessageQueue
Android Looper=/=Handler=/=MessageQueue
classes run message loops for
threads and are used to power the main UI thread by default; and can
optionally be used to run other threads in the app.
The implementation spans both Java and native C++ code to allow running application messages passed along in Java and at the same time using epoll to wait for events.