gevent 聊天室 示例

来源:互联网 发布:知乎红色警戒2 编辑:程序博客网 时间:2024/05/23 11:45

1、http://my.oschina.net/visualgui823/blog/36987

Gevent框架性能很高,但python的GIL模型导致的线程不能抢占多核资源。

而启动多个python进程的这种利用多核的模式又需要增加前端负载均衡,比如lvs那些,有些麻烦。

multiprocessing模块和os.fork又会使得两个进程重复在事件核心注册accept事件,导致文件句柄重复的异常。

至于一个进程监听,多个进程处理的模式,监听的那个进程资源又不好分配——是独立分配一个核心还是不单独分配呢?如果单独分配,连接量小的时候就浪费了一个核心,如果不分配,连接量大的时候cpu又会频繁切换进程。

gevent是可以很轻松地将它的网络模型分布到多个进程并行处理的。

秘诀就在gevent.fork()。gevent.fork能替代os.fork,不仅会启动一个新的进程,而且能将它们底层的事件处理沟通起来,进行并行处理。

import geventfrom gevent.server import StreamServer def eat_cpu():    for i in xrange(10000): pass def cb(socket, address):    eat_cpu()    socket.recv(1024)    socket.sendall('HTTP/1.1 200 OK\n\nHello World!!')    socket.close() server = StreamServer(('',80), cb, backlog=100000)server.pre_start() gevent.fork() server.start_accepting()server._stopped_event.wait()
打上monkey.patch_os后,os.fork就可以被gevent.fork替代了,这样同时multiprocessing模块也可以像往常一样使用,并达到并行处理的效果了。

2、http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001407503089986d175822da68d4d6685fbe849a0e0ca35000

Python通yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:

当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成


3、一个gevent网页聊天室的示例WebSocket with Flask:

路由:

#coding=utf-8import tracebackfrom geventwebsocket.handler import WebSocketHandlerfrom gevent.pywsgi import WSGIServerfrom flask import Flask, request, render_template, abortapp = Flask(__name__)users = {}backlog = deque(maxlen=10)@app.route('/')def index():    print request.url    return render_template('message.html')@app.route('/message/')def message():    if request.environ.get('wsgi.websocket'):        try:            ws = request.environ['wsgi.websocket']            users[id(ws)] = ws            for msg in backlog:                ws.send(msg)            while True:                msg = ws.receive()                if msg:                    backlog.append(msg)                    for user in users:                        if user != id(ws):                            users[user].send(msg)                else:                    print 'close ...'                    break        except Exception,e:            print e            traceback.print_exc()    return "END"if __name__ == '__main__':    print "start server ..."    http_server = WSGIServer(('0.0.0.0', 8000), app, handler_class=WebSocketHandler)    http_server.serve_forever()


模板:

<!doctype html><html>    <head>        <meta charset="utf-8" />        <title>WebSocket Chat Example</title>        <style>            li { list-style: none; }        </style>        <script src="../static/js/jquery-2.1.1.min.js"></script>        <script>            $(document).ready(function() {                function showMessage(message) {                    $('#messages').append('<li>' + message)                }                if (!window.WebSocket) {                    if (window.MozWebSocket) {                        window.WebSocket = window.MozWebSocket;                    } else {                        showMessage("Your browser doesn't support WebSockets")                    }                }                var ws = new WebSocket('ws://" + document.domain + ":8000/message/');                ws.onopen = function(evt) {                    showMessage('Connected to chat.');                };                ws.onmessage = function(evt) {                    showMessage(evt.data);                };                ws.onclose = function(evt) {                    $('#messages').append('<li>WebSocket connection closed.</li>');                };                $('#send-message').submit(function() {                    var message = $('#name').val() + ": " + $('#message').val();                    showMessage(message);                    console.log(message);                    ws.send(message);                    // $('#message').val('').focus();                    return false;                });            });        </script>    </head>    <body>        <h2>WebSocket Chat Example</h2>        <form id="send-message">            <input id="name" type="text" value="name">            <input id="message" type="text" value="message">            <input type="submit" value="Send">        </form>        <div id="messages"></div>    </body></html>



0 0
原创粉丝点击