现在我有两个线程,线程1是主线程,线程2是任务线程。我需要线程2来完成所有网络问题,所以我将所有套接字放在线程2中并将它们设置为无阻塞。线程1用于将请求推送到线程2来完成工作。
起初我写的是这样的:
request_queue = Queue.Queue()
tasks = []
sockets = []
**thread 1:**
while True:
get_user_input()
#...
request_queue.put(request_task)
**thread 2:**
while True:
if have_requests(request_queue):
t = create_task()
tasks.append(t)
sockets.append(t.socket())
select(sockets,timeout=0) #no blocking select
update_tasks()
#...
显然,当没有请求和任务时,线程2会浪费cpu。我不想使用sleep(),因为当线程2处于休眠状态时,它无法及时处理请求。然后我想也许我应该将request_queue更改为本地主机套接字,如下所示:
request_queue = sock.sock()
request_queue.bind(local_host,some_port)
request_queue.listen()
**thread 1**
while True:
get_user_input()
request_queue.send(new_request)
**thread 2**
while True:
select(sockets) # blocking select
if request_queue is active:
t = request_queue.recv()
t = create_task(t)
tasks.append(t)
sockets.append(t.socket())
#check other sockets
#update tasks...
但这看起来有点棘手,我不知道这是否是一个好方法。我想要的是线程2可以及时处理请求,不要浪费cpu时间和处理套接字事件同时。有人可以帮忙吗?
答案 0 :(得分:1)
对于异步网络,请查看Tornado,Twisted或Gevent。 this article也可能对您有用。 Gevent示例:
def handle_socket(sock):
sock.sendall("payload")
sock.close()
server = socket.socket()
server.bind(('0.0.0.0', 9999))
server.listen(500) # max connections
while True:
try:
new_sock, address = server.accept()
except KeyboardInterrupt:
break
# handle every new connection with a new handler
gevent.spawn(handle_socket, new_sock)
Celery最适合后台作业执行。