2010-11-17 12 views
7

Al igual que el siguiente, me gustaría comunicarme con muchas PC en un rango de IP específico.python socket.connect error de tiempo de espera en mulithread o multiproceso

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

Como hay demasiados clientes para comunicarse, lo intenté con mulit-threading. socket.connect() produce continuamente un error de tiempo de espera. Si lo intento en un solo hilo, no hay problema.

que Google y encontró el siguiente:

Python Interpreter blocks Multithreaded DNS requests?

diciendo que de alguna plataforma, módulo de toma de hilo podría ser inseguro.

Así que cambié mi código en multiprocesamiento. Sin embargo, todavía produce el mismo error.

En el siguiente ejemplo de código, test_single() termina normalmente. test_mp() y test_mt() ambos producen un error de tiempo de espera.

¿Alguna vez ha experimentado un comportamiento tan anormal? El entorno de prueba es Windows XP SP3, python 2.5.4. También probado en Python 2.6.6 y 2.7.0, mismo error.

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() 

Respuesta

5

David Beazley ha hecho una gran investigación sobre el Python GIL y cómo eso afecta a IO y multihebra. Puede encontrar información sobre su investigación here, here.

Cuestiones relacionadas