多线程或多进程中的 python socket.connect 超时错误

发布于 2024-10-03 11:07:24 字数 2147 浏览 0 评论 0 原文

如下所示,我想与特定 IP 范围内的许多 PC 进行通信。

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

由于客户端太多无法通信,所以我通过多线程的方式进行了尝试。 socket.connect() 不断产生超时错误。 如果我在单线程中尝试,没有问题。

我用谷歌搜索并找到了以下内容:

Python解释器阻止多线程DNS请求?

说在某些平台上,套接字模块可能是线程不安全的。

所以我将代码更改为多处理。但是它仍然产生相同的错误。

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

Like the following, I'd like to communicate with many PC's in a specific IP range.

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

Because there are too many clients to communicate, I tried it by mulit-threading.
socket.connect() continuously produces time-out error.
If I try it in a single-thread, there's no problem.

I googled and found the below :

Python Interpreter blocks Multithreaded DNS requests?

saying that in some platform, socket module could be thread unsafe.

So I changed my code into multi-processing. However it still produces the same error.

In the following code sample, test_single() finishes normal.
test_mp() and test_mt() both make time-out error.

Have you ever experienced such abnormal behavior?
The testing environment is Windows XP SP3, python 2.5.4.
Also tried on python 2.6.6 and 2.7.0, same 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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等往事风中吹 2024-10-10 11:07:24

David Beazley 围绕 Python GIL 及其如何影响 IO 和多线程做了一些出色的研究。您可以在此处此处

David Beazley has done some great research around the Python GIL and how that affects IO and multithreading. You can find information about his research here, here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文