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)
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)
此外python3 自带一个并法库,没怎么测试用。
自己看以前我的博客