python同時プログラミング

3246 ワード

pythonは、カーネルを直接コンパイルするStackless pythonに加えて、gevent、eventlet greenletなど、比較的際立った概念があり、主な概念は協程である.
以下はブラシチケット(クライアント)の例で、マルチスレッドよりn倍速いが、Stacklessに及ばない:(ps:erlang同時よりpythonベースのコラボレーションStackless)
gevent効率はeventletより高い
import eventlet,time
from eventlet.green import socket
data='''GET /survey.php?PjtID=3809787&SubjID=3886562&OptID=273136&fmt=json&result=0&rdm=0.925835819914937 HTTP/1.1
Host: page.vote.qq.com
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22
Referer: http://hb.qq.com/zt/2013/rgmnew/no1.htm
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: RK=NcDPkbje2o

'''
def send1():
    s=socket.socket()
    s.connect(('page.vote.qq.com',80))
    s.send(data)
    s.close()

send1()
pool=eventlet.GreenPool(512)
while True:pool.spawn_n(send1)

Windowsの下のselect標準ライブラリの同時サーバの例を次に示します.
import socket,select
port=818
data='''HTTP/1.1 200 OK
Server: nginx/0.8.54
Content-Type: text/html
Last-Modified: Thu, 07 Mar 2013 00:03:43 GMT
Access-Control-Allow-Origin: *
Accept-Ranges: bytes
Cache-Control: public, max-age=176022
Expires: Wed, 27 Mar 2013 09:30:34 GMT
Date: Mon, 25 Mar 2013 08:36:52 GMT
Connection: keep-alive

hello world!
'''
n=1
print 'Listen port 818'
service=socket.socket()
service.bind(('',port))
service.listen(1)
while 1:
    is_read=[service]
    is_write=[service]
    is_err=[]
    r,w,e=select.select(is_read, is_write, is_err,1)
    print r,w,e
    if r:
        s,con=service.accept()
        print con,'connected'
        s.recv(1024)
        s.send(data)
        s.close()
    else:
        print 'still waiting',n
        n+=1

次はgeventlet serverモードの同時例です.
import eventlet

def handle(client):
    while True:
        c = client.recv(1)
        if not c: break
        client.sendall(c)

server = eventlet.listen(('0.0.0.0', 6000))
pool = eventlet.GreenPool(10000)
while True:
    new_sock, address = server.accept()
    pool.spawn_n(handle, new_sock)

これはgeventの例で、彼はパッチを持っています.
import gevent
from gevent import monkey
monkey.patch_all()
import socket

tno=500
data='''GET /survey.php?PjtID=3809787&SubjID=3886562&OptID=273136&fmt=json&result=0&rdm=0.925835819914937 HTTP/1.1
Host: page.vote.qq.com
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22
Referer: http://hb.qq.com/zt/2013/rgmnew/no1.htm
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: RK=NcDPkbje2o

'''
def send1():
    s=socket.socket()
    s.connect(('page.vote.qq.com',80))
    s.send(data)
    s.close()
    print "aaaa"

    

jobs = [gevent.spawn(send1) for url in range(tno)]
gevent.joinall(jobs)

またpython 3はパラレルライブラリを持っていて、あまりテストしていません.
以前のブログを自分で見て