2010-11-17 50 views
7

像下面這樣,我想與許多PC在特定IP範圍內進行通信。python socket.connect在mulithread或多進程中的超時錯誤

My PC ---+------> Client A PC 
     +------> Client B PC 
     +------> Client C PC 
     ................. 
     +------> Client Z PC 

因爲有太多的客戶端進行通信,我嘗試了多線程技術。 socket.connect()不斷產生超時錯誤。 如果我在單線程中嘗試它,沒有問題。

我用Google搜索,發現如下:

Python Interpreter blocks Multithreaded DNS requests?

說,在一些平臺上,插座模塊可以線程不安全。

因此,我將我的代碼更改爲多處理。但它仍然會產生相同的錯誤。

在以下代碼示例中,test_single()完成正常。 test_mp()和test_mt()都發生超時錯誤。

你有沒有經歷過這種不正常的行爲? 測試環境是Windows XP SP3,python 2.5.4。 也嘗試在python 2.6.6和2.7.0,同樣的錯誤。

import multiprocessing 
import Queue 
import socket 
import threading 

PROCESS_NUM = 5 
PORT = 8888 

def search_proc(ip): 
    try: 
     csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     csock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     csock.settimeout(5.0) 
     csock.connect((ip, PORT)) 
     csock.shutdown(socket.SHUT_RDWR) 
     csock.close() 
     return ip, "ok" 
    except socket.error, msg: 
     return ip, "fail", msg 

def mp_connect(ip_range): 
    pool = multiprocessing.Pool(PROCESS_NUM) 
    for output in pool.imap_unordered(search_proc, ip_range): 
     print output 

def test_mp(): 
    ip_range = [] 
    for i in range(256): 
     ip_range.append("192.168.123.%d"%(i,)) 

    mp_connect(ip_range) 

def test_mt(): 
    def search_thread(ip_queue): 
     while True: 
      ip = ip_queue.get() 
      print search_proc(ip) 
      ip_queue.task_done() 
    ip_queue = Queue.Queue() 

    for i in range(256): 
     ip_queue.put("192.168.123.%d"%(i,)) 

    for i in range(PROCESS_NUM): 
     th = threading.Thread(target=search_thread, args=(ip_queue,)) 
     th.setDaemon(True) 
     th.start() 

    ip_queue.join() 

def test_single(): 
    ip_range = [] 
    for i in range(256): 
     print search_proc("192.168.123.%d"%(i,)) 

if __name__ == "__main__": 
    multiprocessing.freeze_support() 
    test_mp() 
    #test_single() 
    #test_mt() 

回答

5

David Beazley對Python GIL以及它如何影響IO和多線程做了一些很好的研究。你可以找到他的研究信息herehere