2012-06-12 36 views
0

基本上我只想知道我是否爲併發套接字線程正確實現了線程。這裏是我的方法:我的線程方法是否高效?

#!/usr/bin/env python 
import sys 
import time 
from gevent import socket, Timeout, select 
from gevent.pool import Pool 

def worker(website): 
    data = str() 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.setblocking(0) 
    s.connect(('google.com',80)) 
    s.send('HEAD/HTTP/1.1\n\n') 

    while True: 
     read, w, e = select.select([s], [], []) 
     if read: 
      data = s.recv(1024) 
      if data: 
       break 

    print ('done') 
    return 0 

def main(): 

    pool = Pool(10) 
    for item in items: 
      pool.spawn(worker, item) 
    pool.join() 
+1

而不是檢查'如果讀:',我認爲它可能會更好(更可讀)顯式檢查讀取列表中的套接字:'如果s在讀:'。另外,對於這樣簡單的事情,爲什麼不保持套接字阻塞,並且只是調用'read'呢? –

+0

我錯了嗎,還是在每個greenlet套接字上使用select調用看起來過多?你不是要麼創建所有的套接字並選擇整個集合......要麼使用池方法......在每個套接字上使用'gevent.socket.wait_read(fileno,...)'?或者像@JoachimPileborg建議的那樣,只需將套接字設置爲阻塞,並直接在每個套接字上調用recv? – jdi

+0

如果你只讀一個套接字,我沒有看到任何使用'select'的理由。哎呀,即使你從多個套接字中讀取數據,還是有*沒有理由使用select - 只是產生多個綠色線程來完成讀取,然後讓它們寫入隊列,或者使用'Group.map'來粘貼它們在列表中,或其他任何有意義的東西。 –

回答

1

的螺紋部分(pool.spawn)是好的(雖然Group.map(或imap,或imap_unordered可能是更漂亮)

select是完全沒有必要的,但既然你。使用gevent的修補插槽,你可以用:

data = s.recv(1024) 

一些其他的東西:

  • 如果你這樣做,你不需要撥打setblocking
  • 爲了完全正確,您應該使用socket.sendall
  • 隨着gevent,你幾乎永遠不會select。如果您需要從十個插槽讀取數據,只需產生十個綠色線程即可。例如:結果= Group().map(lambda s: s.read(), my_sockets)
  • 雖然我們在這裏:使用data = str() - data = ""會更加標準。