所以我正在玩无堆栈的python,编写一个非常简单的网络服务器来教我自己用微线程/ tasklet编程.但现在我的问题是,当我ab -n 100000 -c 50 http://192.168.0.192/
在apache工作台运行类似(100k请求,50并发)的东西时,我得到类似6k req/s的东西,第二次运行它我得到5.5k,第三次5k,第四次,4.5k等等一直到100req/s或者其他东西.
但是,当我重新启动python脚本时问题就消失了.
现在我的问题是为什么?我忘记删除tasklets了吗?我已经检查了stackless.getruncount()(由于某种原因它似乎总是返回1)所以它似乎不会有任何死的tasklet挂在身边?我试过在所有完成的tasklet上调用.kill(),没有帮助.我只是想不出这个.
import socket import select import stackless import time class socket_wrapper(object): def __init__(self, sock, sockets): super(socket_wrapper, self).__init__() self.sock = sock self.fileno = sock.fileno self.sockets_list = sockets self.channel = stackless.channel() self.writable = False self.error = False def remove(self): self.sock.close() self.sockets_list.remove(self) def send(self, data): self.sock.send(data) def push(self, bytes): self.channel.send(self.sock.recv(bytes)) def stackless_accept(accept, handler, recv_size=1024, timeout=0): sockets = [accept] while True: read, write, error = select.select(sockets, sockets, sockets, timeout) for sock in read: if sock is accept: # Accept socket and create wrapper sock = socket_wrapper(sock.accept()[0], sockets) # Create tasklett for this connection tasklet = stackless.tasklet(handler) tasklet.setup(sock) # Store socket sockets.append(sock) else: # Send data to handler sock.push(recv_size) # Tag all writable sockets for sock in write: if sock is not accept: sock.writable = True # Tag all faulty sockets for sock in error: if sock is not accept: sock.error = True else: pass # should do something here if the main socket is faulty timeout = 0 if socket else 1 stackless.schedule() def simple_handler(tsock): data = "" while data[-4:] != "\r\n\r\n": data += tsock.channel.receive() while not tsock.writable and not tsock.error: stackless.schedule() if not tsock.error: tsock.send("HTTP/1.1 200 OK\r\nContent-length: 8\r\n\r\nHi there") tsock.remove() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(("192.168.0.192", 8000)) sock.listen(5) stackless.tasklet(stackless_accept)(sock, simple_handler) stackless.run()
S.Lott.. 14
两件事情.
首先,请使用大写字母开头.它更传统,更容易阅读.
更重要的是,在stackless_accept
函数中你积累了一个名为list
的Sock
对象sockets
.这份名单似乎无休止地增长.是的,你有一个remove
,但并不总是被调用.如果套接字出错,那么它似乎将永远留在集合中.
两件事情.
首先,请使用大写字母开头.它更传统,更容易阅读.
更重要的是,在stackless_accept
函数中你积累了一个名为list
的Sock
对象sockets
.这份名单似乎无休止地增长.是的,你有一个remove
,但并不总是被调用.如果套接字出错,那么它似乎将永远留在集合中.