Python socket.connect 多线程或多进程超时错误

7 投票
1 回答
3088 浏览
提问于 2025-04-16 07:13

我想和很多电脑进行通信,这些电脑的IP地址在一个特定的范围内。

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

因为要沟通的客户端太多了,所以我尝试使用多线程来处理。但是,socket.connect() 一直出现超时错误。如果我用单线程来做,就没有问题。

我在网上查了一下,发现了下面这个链接:

Python解释器会阻塞多线程的DNS请求吗?

里面提到在某些平台上,socket模块可能不安全,不能在多个线程中同时使用。

于是我把代码改成了多进程,但还是出现了同样的错误。

在下面的代码示例中,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()

1 个回答

5

David Beazley 对 Python 的全局解释器锁(GIL)做了一些很棒的研究,这个锁是如何影响输入输出(IO)和多线程的。他的研究信息可以在这里这里找到。

撰写回答