SlideShare a Scribd company logo
How do event loops
 work in Python?
    Saúl Ibarra Corretgé




      FOSDEM 2013
print(self)

• Hi there!

• @saghul

• I work on VoIP and Real Time Communications

• Python and C are my tools
try: sockets
from __future__ import print_function

import socket

server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
server.bind(('127.0.0.1', 1234))
server.listen(10)
print("Server listening on: {}".format(server.getsockname()))

client, addr = server.accept()
print("Client connected: {}".format(addr))

while True:
    data = client.recv(4096)
    if not data:
        print("Client has disconnected")
        break
    client.send(data.upper())

server.close()
except Exception:
• We can only handle one client at a time!

• Solutions for handling multiple clients

   • Threads

   • I/O multiplexing

• Check the C10K problem if you haven’t already!

   • http://www.kegel.com/c10k.html
try: sockets + threads
from __future__ import print_function

import socket
import thread

def handle_client(client, addr):
    print("Client connected: {}".format(addr))
    while True:
        data = client.recv(4096)
        if not data:
            print("Client has disconnected")
            break
        client.send(data.upper())

server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
server.bind(('127.0.0.1', 1234))
server.listen(10)
print("Server listening on: {}".format(server.getsockname()))

while True:
    client, addr = server.accept()
    thread.start_new_thread(handle_client, (client, addr))
except Exception:
• Threads have overhead

  • Stack size

  • Context switching

• Synchronization

• GIL?

  • Not for I/O!
I/O multiplexing
• Examine and block for I/O in multiple file
  descriptors at the same time

   • Single thread

• A file descriptor is ready if the corresponding I/O
  operation can be performed without blocking

• File descriptor has to be set to be non-blocking
I/O multiplexing (II)

1. Put file descriptors in non-blocking mode

2. Add file descriptors to a I/O multiplexor

3. Block for some time

4. Perform blocking operations on file descriptors
   which are ready
def set_nonblocking
def set_nonblocking(fdobj):
    try:
         setblocking = fdobj.setblocking
    except AttributeError:
         try:
              import fcntl
         except ImportError:
              raise NotImplementedError
         try:
              fd = fdobj.fileno()
         except AttributeError:
              fd = fdobj
         flags = fcntl.fcntl(fd, fcntl.F_GETFL)
         fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
    else:
         setblocking(False)
select

• Lowest common denominator I/O multiplexor

• Takes a list of “readers”, “writers”, “exceptional
  conditions” and a timeout

• Limit of FD_SETSIZE file descriptors, usually 1024

• Processing takes O(number of fds)
How do event loops work in Python?
epoll

• “A better select”

• No FD_SETSIZE limit!

• Processing takes O(1) time!

• Linux only
Other I/O
         multiplexors
• kqueue

  • Like epoll but for Max OSX and BSD

• poll

  • Like select but without a limit of file descriptors

  • O(number of file descriptors) processing time

  • Very broken on some systems (OSX 10.3-5)
sys.platform == “win32”
  • Windows supports select

     • 64 file descriptors per thread - WAT

  • Starting with Vista WSAPoll (poll) is supported

     • It’s broken - http://daniel.haxx.se/blog/
       2012/10/10/wsapoll-is-broken/

  • IOCP is the good stuff

     • Based on completion, not readiness
edge/level triggering
• Level triggering (the most common)

   • You get notified when the condition is present

• Edge triggering

   • You get notified when the condition happens

• epoll and kqueue support both mechanisms

• IOCP is kind-of edge-triggered epoll
How do event loops work in Python?
Event loop libraries
            epoll, IOCP on
                           File I/O
           kqueue windows

 libev      YES      NO      libeio

libevent    YES      YES      NO

 libuv      YES      YES      YES
Event loop libraries
        (II)
        1. Update loop time

         2. Process timers

      3. Process idle handles

     4. Process prepare handles

          5. Block for I/O

     6. Process check handles
libuv: the power
underneath nodeJS
nodeJS <= 0.4.x

                   node standard library
JavaScript

  C / C++
                      node bindings


              V8           libev       libeio
nodeJS >= 0.6.x

                   node standard library
JavaScript

  C / C++
                      node bindings


              V8                 libuv
libuv
• Originally based on libev + libeio + IOCP

• Now: epoll + kqueue + event ports + IOCP + file I/O

• TCP, UDP, named pipes, TTY

• Nice additions: interface addresses, process title, ...

• Most complete cross platform networking library

• Python bindings - pyuv
import pyuv

• Written in C, wraps everything libuv has to offer

• Python >= 2.6, supports Python 3!

• Works on Windows

• https://github.com/saghul/pyuv
from __future__ import print_function

import signal
import pyuv

def on_read(client, data, error):
    if data is None:
        print("Client read error: {}".format(pyuv.errno.strerror(error)))
        client.close()
        clients.remove(client)
        return
    client.write(data.upper())

def on_connection(server, error):
    client = pyuv.TCP(server.loop)
    server.accept(client)
    clients.append(client)
    client.start_read(on_read)
    print("Client connected: {}".format(client.getpeername()))

def signal_cb(handle, signum):
    [c.close() for c in clients]
    signal_h.close()
    server.close()

clients = []
loop = pyuv.Loop.default_loop()
server = pyuv.TCP(loop)
server.bind(("127.0.0.1", 1234))
server.listen(on_connection)
signal_h = pyuv.Signal(loop)
signal_h.start(signal_cb, signal.SIGINT)
loop.run()
import pyuv

• Experiments in replacing event loops of common
  Python networking frameworks

  • Twisted - https://github.com/saghul/twisted-pyuv

  • Tornado - https://github.com/saghul/tornado-pyuv

  • Gevent - https://github.com/saghul/uvent
import pyuv

• gaffer: application deployment and supervisor

   • https://github.com/benoitc/gaffer

• ts_analyzer: realtime analysis of multicast video
  streams

   • https://github.com/tijmenNL/ts_analyzer
The Python
 async I/O problem
• Each framework uses it’s own event loop
  implementation

• Protocols aren’t reusable

• PEP-3156 to the rescue!

   • For Python >= 3.3

• Reference implementation (Tulip)
  https://code.google.com/p/tulip/
import rose

• PEP-3156 EventLoop implementation using pyuv

• pyuv.Poll: high performance level triggered I/O
  (works on Windows as well!)

   • Uses fairy dust covered unicorns

• https://github.com/saghul/rose
import rose
import signal
from rose import events, protocols

class EchoProtocol(protocols.Protocol):
    def connection_made(self, transport):
        # TODO: Transport should probably expose getsockname/getpeername
        print("Client connected: {}".format(transport._sock.getpeername()))
        self.transport = transport
    def data_received(self, data):
        self.transport.write(data.upper())
    def eof_received(self):
        self.transport.close()
    def connection_lost(self, exc):
        print("Client closed connection")

reactor = events.new_event_loop()
events.set_event_loop(reactor)

reactor.start_serving(EchoProtocol, '127.0.0.1', 1234)
reactor.add_signal_handler(signal.SIGINT, reactor.stop)

reactor.run()
How do event loops work in Python?
saghul

More Related Content

PPT
Introduction to Python
PPTX
GDG Helwan Introduction to python
PPTX
Introduction to OOP in Python
PDF
Python functions
PDF
Q2.12: Debugging with GDB
PPTX
exception handling in cpp
PDF
Get started python programming part 1
Introduction to Python
GDG Helwan Introduction to python
Introduction to OOP in Python
Python functions
Q2.12: Debugging with GDB
exception handling in cpp
Get started python programming part 1

What's hot (20)

PPTX
Hibernate
PPTX
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
PDF
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
PPT
PPTX
Introduction to the basics of Python programming (part 1)
PDF
Python ders-notlari
PDF
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
PPTX
Intro to Python Programming Language
PPT
Java Tutorial
PPTX
Python Lambda Function
PPTX
Python-Classes.pptx
PDF
Python Tutorial
PDF
Operating system lab manual
PDF
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PPTX
Command Line Arguments in C#
PDF
Ruby on Rails Presentation
PDF
Android Binder IPC for Linux
PPTX
Hibernate
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
Introduction to the basics of Python programming (part 1)
Python ders-notlari
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
Intro to Python Programming Language
Java Tutorial
Python Lambda Function
Python-Classes.pptx
Python Tutorial
Operating system lab manual
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Command Line Arguments in C#
Ruby on Rails Presentation
Android Binder IPC for Linux
Ad

Viewers also liked (12)

PDF
A deep dive into PEP-3156 and the new asyncio module
PDF
Vert.x – The problem of real-time data binding
PDF
Functional Programming & Event Sourcing - a pair made in heaven
PDF
Python, do you even async?
PPTX
Async programming and python
PPTX
Building microservices with vert.x 3.0
PDF
Pythonによる非同期プログラミング入門
PDF
Python RESTful webservices with Python: Flask and Django solutions
PPTX
Web backends development using Python
PDF
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
PDF
Namespaces and cgroups - the basis of Linux containers
PDF
An Introduction to Python Concurrency
A deep dive into PEP-3156 and the new asyncio module
Vert.x – The problem of real-time data binding
Functional Programming & Event Sourcing - a pair made in heaven
Python, do you even async?
Async programming and python
Building microservices with vert.x 3.0
Pythonによる非同期プログラミング入門
Python RESTful webservices with Python: Flask and Django solutions
Web backends development using Python
Introduction to WAMP, a protocol enabling PUB/SUB and RPC over Websocket
Namespaces and cgroups - the basis of Linux containers
An Introduction to Python Concurrency
Ad

Similar to How do event loops work in Python? (20)

PDF
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilities
PPTX
introduction to node.js
PDF
WTF is Twisted?
PDF
"You Don't Know NODE.JS" by Hengki Mardongan Sihombing (Urbanhire)
PDF
Balázs Bucsay - XFLTReaT: Building a Tunnel
PPTX
How NOT to write in Node.js
KEY
Introdution to Node.js
KEY
node.js: Javascript's in your backend
PDF
Original slides from Ryan Dahl's NodeJs intro talk
PDF
Tornado Web Server Internals
PDF
Introduction to Node.js
KEY
Introduction to NodeJS with LOLCats
PPTX
Node.js: The What, The How and The When
PPTX
Utilizing the OpenNTF Domino API
PDF
Node.js introduction
PDF
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
PDF
Nodejs - Should Ruby Developers Care?
PDF
DevopsItalia2015 - DHCP at Facebook - Evolution of an infrastructure
PDF
Introduction to Node.js: What, why and how?
PDF
FITC - Node.js 101
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilities
introduction to node.js
WTF is Twisted?
"You Don't Know NODE.JS" by Hengki Mardongan Sihombing (Urbanhire)
Balázs Bucsay - XFLTReaT: Building a Tunnel
How NOT to write in Node.js
Introdution to Node.js
node.js: Javascript's in your backend
Original slides from Ryan Dahl's NodeJs intro talk
Tornado Web Server Internals
Introduction to Node.js
Introduction to NodeJS with LOLCats
Node.js: The What, The How and The When
Utilizing the OpenNTF Domino API
Node.js introduction
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
Nodejs - Should Ruby Developers Care?
DevopsItalia2015 - DHCP at Facebook - Evolution of an infrastructure
Introduction to Node.js: What, why and how?
FITC - Node.js 101

More from Saúl Ibarra Corretgé (20)

PDF
JanusCon 2024: Mom there are robots in my meeting
PDF
Challenges running Jitsi Meet at scale during the pandemic
PDF
The Road to End-to-End Encryption in Jitsi Meet
PDF
Jitsi: State of the Union 2020
PDF
Jitsi Meet: our tale of blood, sweat, tears and love
PDF
Jitsi Meet: Video conferencing for the privacy minded
PDF
Jitsi - Estado de la unión 2019
PDF
Get a room! Spot: the ultimate physical meeting room experience
PDF
Going Mobile with React Native and WebRTC
PDF
Going Mobile with React Native and WebRTC
PDF
Jitsi: Estado de la Unión (2018)
PDF
Jitsi: state-of-the-art video conferencing you can self-host
PDF
WebRTC: El epicentro de la videoconferencia y IoT
PDF
Jitsi: Open Source Video Conferencing
PDF
Jitsi: State of the Union
PDF
libuv: cross platform asynchronous i/o
PDF
Videoconferencias: el santo grial de WebRTC
PDF
SylkServer: State of the art RTC application server
PDF
Escalabilidad horizontal desde las trincheras
PDF
A deep dive into libuv
JanusCon 2024: Mom there are robots in my meeting
Challenges running Jitsi Meet at scale during the pandemic
The Road to End-to-End Encryption in Jitsi Meet
Jitsi: State of the Union 2020
Jitsi Meet: our tale of blood, sweat, tears and love
Jitsi Meet: Video conferencing for the privacy minded
Jitsi - Estado de la unión 2019
Get a room! Spot: the ultimate physical meeting room experience
Going Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTC
Jitsi: Estado de la Unión (2018)
Jitsi: state-of-the-art video conferencing you can self-host
WebRTC: El epicentro de la videoconferencia y IoT
Jitsi: Open Source Video Conferencing
Jitsi: State of the Union
libuv: cross platform asynchronous i/o
Videoconferencias: el santo grial de WebRTC
SylkServer: State of the art RTC application server
Escalabilidad horizontal desde las trincheras
A deep dive into libuv

Recently uploaded (20)

PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
A Presentation on Artificial Intelligence
PDF
Electronic commerce courselecture one. Pdf
PDF
KodekX | Application Modernization Development
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPT
Teaching material agriculture food technology
PDF
Modernizing your data center with Dell and AMD
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Machine learning based COVID-19 study performance prediction
Digital-Transformation-Roadmap-for-Companies.pptx
A Presentation on Artificial Intelligence
Electronic commerce courselecture one. Pdf
KodekX | Application Modernization Development
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Chapter 3 Spatial Domain Image Processing.pdf
Unlocking AI with Model Context Protocol (MCP)
Agricultural_Statistics_at_a_Glance_2022_0.pdf
MYSQL Presentation for SQL database connectivity
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Building Integrated photovoltaic BIPV_UPV.pdf
Teaching material agriculture food technology
Modernizing your data center with Dell and AMD
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Understanding_Digital_Forensics_Presentation.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...

How do event loops work in Python?

  • 1. How do event loops work in Python? Saúl Ibarra Corretgé FOSDEM 2013
  • 2. print(self) • Hi there! • @saghul • I work on VoIP and Real Time Communications • Python and C are my tools
  • 3. try: sockets from __future__ import print_function import socket server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) server.bind(('127.0.0.1', 1234)) server.listen(10) print("Server listening on: {}".format(server.getsockname())) client, addr = server.accept() print("Client connected: {}".format(addr)) while True: data = client.recv(4096) if not data: print("Client has disconnected") break client.send(data.upper()) server.close()
  • 4. except Exception: • We can only handle one client at a time! • Solutions for handling multiple clients • Threads • I/O multiplexing • Check the C10K problem if you haven’t already! • http://www.kegel.com/c10k.html
  • 5. try: sockets + threads from __future__ import print_function import socket import thread def handle_client(client, addr): print("Client connected: {}".format(addr)) while True: data = client.recv(4096) if not data: print("Client has disconnected") break client.send(data.upper()) server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) server.bind(('127.0.0.1', 1234)) server.listen(10) print("Server listening on: {}".format(server.getsockname())) while True: client, addr = server.accept() thread.start_new_thread(handle_client, (client, addr))
  • 6. except Exception: • Threads have overhead • Stack size • Context switching • Synchronization • GIL? • Not for I/O!
  • 7. I/O multiplexing • Examine and block for I/O in multiple file descriptors at the same time • Single thread • A file descriptor is ready if the corresponding I/O operation can be performed without blocking • File descriptor has to be set to be non-blocking
  • 8. I/O multiplexing (II) 1. Put file descriptors in non-blocking mode 2. Add file descriptors to a I/O multiplexor 3. Block for some time 4. Perform blocking operations on file descriptors which are ready
  • 9. def set_nonblocking def set_nonblocking(fdobj): try: setblocking = fdobj.setblocking except AttributeError: try: import fcntl except ImportError: raise NotImplementedError try: fd = fdobj.fileno() except AttributeError: fd = fdobj flags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) else: setblocking(False)
  • 10. select • Lowest common denominator I/O multiplexor • Takes a list of “readers”, “writers”, “exceptional conditions” and a timeout • Limit of FD_SETSIZE file descriptors, usually 1024 • Processing takes O(number of fds)
  • 12. epoll • “A better select” • No FD_SETSIZE limit! • Processing takes O(1) time! • Linux only
  • 13. Other I/O multiplexors • kqueue • Like epoll but for Max OSX and BSD • poll • Like select but without a limit of file descriptors • O(number of file descriptors) processing time • Very broken on some systems (OSX 10.3-5)
  • 14. sys.platform == “win32” • Windows supports select • 64 file descriptors per thread - WAT • Starting with Vista WSAPoll (poll) is supported • It’s broken - http://daniel.haxx.se/blog/ 2012/10/10/wsapoll-is-broken/ • IOCP is the good stuff • Based on completion, not readiness
  • 15. edge/level triggering • Level triggering (the most common) • You get notified when the condition is present • Edge triggering • You get notified when the condition happens • epoll and kqueue support both mechanisms • IOCP is kind-of edge-triggered epoll
  • 17. Event loop libraries epoll, IOCP on File I/O kqueue windows libev YES NO libeio libevent YES YES NO libuv YES YES YES
  • 18. Event loop libraries (II) 1. Update loop time 2. Process timers 3. Process idle handles 4. Process prepare handles 5. Block for I/O 6. Process check handles
  • 20. nodeJS <= 0.4.x node standard library JavaScript C / C++ node bindings V8 libev libeio
  • 21. nodeJS >= 0.6.x node standard library JavaScript C / C++ node bindings V8 libuv
  • 22. libuv • Originally based on libev + libeio + IOCP • Now: epoll + kqueue + event ports + IOCP + file I/O • TCP, UDP, named pipes, TTY • Nice additions: interface addresses, process title, ... • Most complete cross platform networking library • Python bindings - pyuv
  • 23. import pyuv • Written in C, wraps everything libuv has to offer • Python >= 2.6, supports Python 3! • Works on Windows • https://github.com/saghul/pyuv
  • 24. from __future__ import print_function import signal import pyuv def on_read(client, data, error): if data is None: print("Client read error: {}".format(pyuv.errno.strerror(error))) client.close() clients.remove(client) return client.write(data.upper()) def on_connection(server, error): client = pyuv.TCP(server.loop) server.accept(client) clients.append(client) client.start_read(on_read) print("Client connected: {}".format(client.getpeername())) def signal_cb(handle, signum): [c.close() for c in clients] signal_h.close() server.close() clients = [] loop = pyuv.Loop.default_loop() server = pyuv.TCP(loop) server.bind(("127.0.0.1", 1234)) server.listen(on_connection) signal_h = pyuv.Signal(loop) signal_h.start(signal_cb, signal.SIGINT) loop.run()
  • 25. import pyuv • Experiments in replacing event loops of common Python networking frameworks • Twisted - https://github.com/saghul/twisted-pyuv • Tornado - https://github.com/saghul/tornado-pyuv • Gevent - https://github.com/saghul/uvent
  • 26. import pyuv • gaffer: application deployment and supervisor • https://github.com/benoitc/gaffer • ts_analyzer: realtime analysis of multicast video streams • https://github.com/tijmenNL/ts_analyzer
  • 27. The Python async I/O problem • Each framework uses it’s own event loop implementation • Protocols aren’t reusable • PEP-3156 to the rescue! • For Python >= 3.3 • Reference implementation (Tulip) https://code.google.com/p/tulip/
  • 28. import rose • PEP-3156 EventLoop implementation using pyuv • pyuv.Poll: high performance level triggered I/O (works on Windows as well!) • Uses fairy dust covered unicorns • https://github.com/saghul/rose
  • 29. import rose import signal from rose import events, protocols class EchoProtocol(protocols.Protocol): def connection_made(self, transport): # TODO: Transport should probably expose getsockname/getpeername print("Client connected: {}".format(transport._sock.getpeername())) self.transport = transport def data_received(self, data): self.transport.write(data.upper()) def eof_received(self): self.transport.close() def connection_lost(self, exc): print("Client closed connection") reactor = events.new_event_loop() events.set_event_loop(reactor) reactor.start_serving(EchoProtocol, '127.0.0.1', 1234) reactor.add_signal_handler(signal.SIGINT, reactor.stop) reactor.run()