You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于UDP的代理隧道线程阻塞与CPU占用过高问题排查

代理隧道CPU占用过高、阻塞严重问题排查

基于pysoxy实现代理隧道,将代理拆分为处理客户端连接的本地端,以及处理目标端代理的远程端,两端通过UDP通信。但加载简单页面时就出现100% CPU占用,性能极差,线程阻塞严重——即便在非阻塞代码行之间也存在长达1.5秒的延迟,且键盘中断几乎无法被捕获以正常关闭线程。

怀疑问题出在UDP套接字的使用上,虽尝试避免阻塞IO,但问题仍存在。核心代码如下:

def proxy_loop_inbound(destination_socket, connection_details, stop_event, connection_queue):
    while not EXIT.get_status() or not stop_event.is_set():
        with connection_queue["lock"]:
            for index, proxy_loop in enumerate(connection_queue["queues"]):
                if int(proxy_loop["id"]) == connection_details["id"]:
                    proxy_loop_content = base64.b64decode(proxy_loop["proxy_loop"])
                    if int(proxy_loop["sequence"])==inbound_sequence:
                        del connection_queue["queues"][index]
                        while True:
                            _, ready_to_write, _ = select.select([], [destination_socket], [], 0.01)
                            if ready_to_write:
                                break  # Break the loop if the socket is ready to write
                            time.sleep(0.01)  # Sleep for a short duration to yield to other threads
                        destination_socket.send(proxy_loop_content)
                        break
                    else:
                        pass

def proxy_loop_outbound(destination_socket, connection_details, stop_event):
    while not EXIT.get_status() or not stop_event.is_set():
        try:
            ready_to_read, _, _ = select.select([destination_socket], [], [], 1)
            if destination_socket in ready_to_read:
                data = destination_socket.recv(BUFSIZE)
                if not data:
                    return
                while True:
                    _, ready_to_write, _ = select.select([], [udp_socket], [], 0.01)
                    if ready_to_write:
                        break  # Break the loop if the socket is ready to write
                    time.sleep(0.01)  # Sleep for a short duration to yield to other threads
                udp_socket.sendto(proxy_loop_outbound_details.encode(), ("127.0.0.1", UDP_PORT_WRITE))
        except BlockingIOError:
            print("Blocking IO error")
            pass
            # No data available
        except socket.error as err:
            stop_event.set()
            error("Loop failed", err)
            return

每个连接会生成两个上述线程,UDP监听线程会将可能乱序的数据存入线程共享列表。请问哪里操作出错了?

内容的提问来源于stack exchange,提问作者Marco Carandente

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:40:13