应选用支持协程的网络库(如Boost.Fibers)而非Boost.Asio同步模式或libuv;需调大系统接收缓冲区、关闭多播回环、避免std::thread每连接一线程模型,改用小栈协程共享OS线程,并精细控制内存分配与CPU绑定。

用什么网络库扛住万级订单并发
别碰 Boost.Asio 的同步模式,也别直接上 libuv 做胶水层——高并发网关的瓶颈不在协议解析,而在连接管理与内存零拷贝。国内主流柜台(如恒生UFT、顶点TradeStation)要求单节点支撑 5000+ TCP 连接、端到端延迟 io_uring(Linux 5.1+)或 epoll + SO_REUSEPORT 分发,配合无锁环形缓冲区收发消息。示例中常见错误是把 std::string 当作报文载体反复构造析构,实际应预分配固定长度内存池,用 char* 指针+长度字段管理原始字节流。
如何避免订单乱序和重复提交
交易所对订单顺序极其敏感,recv() 返回的字节流不等于业务消息边界。不能依赖 std::getline() 或简单查找分隔符。正确做法是:在协议头固定 4 字节长度字段(大端),用 readv() 两次读取(先读头,再按长度读体),全程禁止跨线程共享 socket fd。关键陷阱是多个工作线程共用一个 epoll_wait() 实例却没做 EPOLLONESHOT 标记,导致同一事件被多个线程消费,引发订单重复解析。另外,所有订单必须带本地单调递增序列号(非时间戳),由网关统一生成并透传至柜台,用于事后对账校验。
行情订阅怎么做到低延迟且不丢包
UDP 多播是唯一选择,但默认内核 net.core.rmem_max 通常只有 212992 字节,远不够承载 Level2 行情洪峰(实测某券商行情源峰值 > 8MB/s)。必须提前调大:sysctl -w net.core.rmem_max=16777216,并在代码中用 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) 双重加固。更隐蔽的问题是:用 bind() 绑定任意端口后未调用 setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &off, sizeof(off)) 关闭回环,导致本机订阅者收到两份相同行情,干扰时序判断。
为什么不能用 std::thread 管理连接
每连接一线程模型在 2000+ 并发下必然崩溃——不是因为性能差,而是 pthread_create() 默认栈大小 8MB,2000 连接即占用 16GB 虚拟内存,触发 OOM killer。必须用 boost::fibers 或手写协程调度器(基于 ucontext 或 makecontext),让数千连接共享几十个 OS 线程。注意:GCC 12+ 的 std::jthread 不解决此问题,它只是带自动 join 的 std::thread 包装,底层仍是 1:1 线程模型。真实生产环境里,协程栈大小设为 64KB 是平衡安全与内存的常见值。
真正难的不是写出让程序跑起来的代码,而是让每个 socket 的 send() 调用在 99.99% 场景下不阻塞、不让出 CPU、不触发页错误——这要求你亲手控制内存分配路径、中断亲和性绑定、以及网卡 RSS 队列与 CPU 核心的严格映射。这些细节不会出现在任何 C++ 教程里。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











