2016-01-13 144 views
2

現在我有兩個線程,線程1是主線程和線程2是thread.I需要線程2做的所有網絡問題的任務,所以我把所有的插座中的線程2,並將其設置爲無堵塞。線程1用於將請求推送到線程2來完成這項工作。蟒蛇異步Socket編程

起初,我寫的是這樣的:

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.I不想使用睡眠(),因爲當線程2睡覺,它無法處理請求在time.Then我想,也許我應該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

爲什麼Thread2不是從隊列中簡單地[消耗道具](https://docs.python.org/3/library/queue.html#queue.Queue.get)? (阻塞) – Pynchia

+0

因爲它創建隊列任務物品,然後將處理套接字事件了。 –

回答

1

對於異步網絡,請參閱TornadoTwistedGevent。也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是最合適的後臺作業執行。

+1

我想要做的更像是一個線程池等待請求,而不是服務器。我會在稍後閱讀。 –

+2

....或只是https://docs.python.org/3/library/asyncio.html? – xtofl

+1

是的,如果我寫一個服務器,那麼這是很好的。但現在,我需要服務器同時處理來自其他線程和異步套接字事件的新請求。順便說一下,我使用的是Python 2.7。 –