作者小头像 Lv.1
42 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据
个人勋章
  • 活跃之星
成长雷达
15
27
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据

达成规则

发布时间 2026/10/22 07:35:43 最后回复 yd_239575663 2026/10/22 18:11:46 版块 开发者空间
51 22 0
发布时间 2026/10/22 10:07:42 最后回复 yd_219023509 2026/10/22 18:19:59 版块 智慧园区
25 6 0
发布时间 2026/10/22 10:31:41 最后回复 yd_235361064 2026/10/22 14:49:32 版块 智慧园区
44 9 0
发布时间 2026/10/21 21:03:23 最后回复 yd_298885195 2026/10/21 21:04:01 版块 智慧园区
7 2 0
发布时间 2026/10/21 17:33:21 最后回复 yd_211245207 2026/10/21 17:34:39 版块 开发者空间
8 1 0
他的回复:
先说结论:TIME_WAIT 是主动关闭方的「保险期」,解决两个问题——最后 ACK 丢失后的可靠终止、旧报文污染新连接。它不是浪费,设计上就是拿 2MSL 的时间换正确性。作用一:可靠终止连接。四次挥手最后一步,主动关闭方发出 ACK 后立即进入 TIME_WAIT。如果这个 ACK 在路上丢了,被动关闭方收不到,会重传 FIN;主动关闭方必须保留连接上下文,才能重新发 ACK。没有 TIME_WAIT,收到重传 FIN 只能回 RST,对端会把「正常关闭」当成「连接错误」处理。作用二:让旧报文自然消亡。TCP 四元组(源IP/源端口/目的IP/目的端口)可能被快速复用。若旧连接的延迟报文(在网络里漂了数十秒)在复用后的新连接到达,序号可能恰好落在接收窗口内,直接污染数据流。等一个 2MSL(报文最大生存时间的两倍),让旧报文全部死在网络里,新连接才安全。这也是为什么 Linux 内核移除了 tcp_tw_recycle——它按源 IP 时间戳做快速回收,NAT 环境下多主机时间戳错乱,导致大量连接被误杀。什么时候会成为瓶颈,怎么处理:1. 客户端端口耗尽:作为压测客户端或高频外呼方,本机临时端口 28232 个(ip_local_port_range 默认 32768~60999)很快被 TIME_WAIT 占满,报「Cannot assign requested address」。解法是开 tcp_tw_reuse=1(仅对客户端发起连接有效,依赖时间戳选项),或改用长连接/连接池,从根上减少握手次数。2. 服务端 TIME_WAIT 多但无害:服务端主动关闭才产生 TIME_WAIT,留在监听端口的 TIME_WAIT 不占新端口,内核用 hash 表管理,几万个也只是内存开销,通常不用管。3. 真正的工程解法:让「谁主动关闭」落在合适的一侧——HTTP 服务端设置 Connection: keep-alive 让客户端先关;数据库/中间件用连接池避免频繁建连。一句话总结:TIME_WAIT 多不是事故本身,它说明你在频繁建连。先看它是客户端还是服务端产生的,再决定用 tw_reuse、长连接还是连接池,直接动 tcp_tw_recycle 是历史遗留的正确性陷阱,别碰。
发布时间 2026/10/21 15:52:15 最后回复 yd_265768724 2026/10/22 15:10:39 版块 开发者空间
30 5 0
他的回复:
ABA 问题是无锁编程(CAS)里最隐蔽的一类坑:线程 1 读到变量值是 A,被挂起;期间线程 2 把值改成 B 又改回 A;线程 1 恢复后执行 CAS(A→C),比较成功——但内存状态其实已经变过两轮,中间发生的副作用(节点被释放又复用、计数被清零又填回)全部被掩盖。经典复现场景:无锁栈的 pop。线程 1 记下栈顶 A,还没来得及 CAS;线程 2 pop 掉 A、B,又 push 回一个地址恰好等于 A 的新节点;线程 1 的 CAS(top, A, A->next) 成功,但此时 A->next 早已不是它当年读到的值,栈直接被打断链。工程上的解法:1. 版本号戳(推荐):把“值+版本”打包成 128 位做 CAS。Java 用 AtomicStampedReference(stamp 每次修改 +1)或 AtomicMarkableReference(布尔标记位);C++ 可用 __sync_bool_compare_and_swap 操作 16 字节或引入 DW-CAS。2. 延迟回收:ABA 危害大多来自内存复用。用 hazard pointer、epoch-based reclamation 或 RCU 把“别人可能还引用着”的节点推迟释放,从根上切断复用。3. 语言层面规避:有 GC 的语言(Java 引用类型字段)通常不会把同一地址重新分配给新对象,纯 JVM 场景 ABA 风险低;但涉及 unsafe、堆外内存、共享内存时依然存在。一句话判断要不要防:CAS 的比较对象是“裸地址/裸值”且中间状态会被回收复用(C/C++、共享内存)就必须防;只是普通计数器(值单调递增,不会回到旧值)天然无 ABA。