基于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
相关产品推荐
相关产品推荐

