eventlet implementation explained 1

來源:互聯網
上載者:User

Eventlet is an asynchronouse I/O library which is based on

greenlet. We can write very efficient network programms with eventlet without using threads. So let’s see how it is implemented. We start from an echo server example which you can find in eventlet.

#! /usr/bin/env python"""/Simple server that listens on port 6000 and echos back every input tothe client.  To try out the server, start it up by running this file.Connect to it with:  telnet localhost 6000You terminate your connection by terminating telnet (typically Ctrl-]and then 'quit')"""import eventletdef handle(fd):    print "client connected"    while True:        # pass through every non-eof line        x = fd.readline()        if not x: break        fd.write(x)        fd.flush()        print "echoed", x,    print "client disconnected"print "server socket listening on port 6000"server = eventlet.listen(('0.0.0.0', 6000))pool = eventlet.GreenPool()while True:    try:        new_sock, address = server.accept()        pool.spawn_n(handle, new_sock.makefile('rw'))    except (SystemExit, KeyboardInterrupt):        break

At first look, everything seems to be blocking. But note that no standard library is explicitly imported, the socket we use is provided by eventlet, which is non-blocking by default.

We need to launch a debugger (I use spe with winpdb) to see what really happens insided eventlet. Let me present you the stack trace.

socket.accept    socket_accept(fd)        py.socket.accept # standard api is called            return None for non-blocking if no incoming connection            return Not None if has incoming connection        trampoline # if no incomming connection            hub.add # add a FdListener                add the listener to the queue correponding the fd(socket)                callback of the listener is greenlet.current.switch which is the main thread            hub.switch                hub.greenlet.switch # run = hub.run (hub -> BaseHub                    BaseHub.run # main loop, this is a greenlet                        prepare_timers # sort timers                        fire_timers    # fire timers with current tick                        prepare_timers # why ???                        wait # wait a period of timer                            py.select.select # wait                            if has avail readers                                FdListeners[0](fd) # notify the listerner, read/write can be performed without blocking,                                                   # callback is to switch to trampoline            hub.remove # remove a listener, we reach here if there're some read/write events

If there’s no incoming connection, trampoline is called. This function is very important to eventlet, such as accept, recv, readline will call this function inside. Within trampoline, a listener is added
to a the hub which is the core of eventlet. When there’s any read/write events, corresponding listeners will be called, so that we can at on the events. The callback of listeners are greenlet which by default are the main greenlet. In this example, if there’s
a client connecting to the server, a listerner is notified. Remember that the callback of a listener is a greenlet, which is by default the main greenlet, this means that we will switch back to trampoline, and then return to our main loop to spawn a new handler.

Now we are spawning a handler, below is the stack trace of spawn_n.

GreenPool.spawn_n    greenthread.spawn_n        _spawn_n # create a greenlet of the client handler        hub.schedule_call_global # create a corresponding timer, and then add the timer to a list which is a priority queue.

GreenPool.spawn_n just creates a timer which will be process when accept is called in the next loop run. The timer contains a greenlet which wraps our handle function.

In next loop, server.accept is called again. Assume that there’s no new incoming connection, trampoline is called and we will switch to the main loop. Timers will be processed, our handle function is called.
If there’s no recving data, we then switching to the main loop.

It’s a bit complex, since the control flow is not linear. After you have a basic grasp of what’s going on, you will be fine.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.