解决了一个困惑很久的 bug

本贴最后更新于 2644 天前,其中的信息可能已经渤澥桑田

让这个 bug 困扰了很久,前一段太忙只找了个临时解决方案而没有追究原因,今天终于把它搞清楚了。由于测试时只在多 CPU 系统上出现,我甚至一度怀疑它是 CPU 的 bug😂 。

两个 c/s 结构的网络通讯程序,服务器端使用完成端口模型,客户端使用阻塞模型,双方以一种客户端发送命令,服务器端处理,然后返回应答的方式通讯。问题出在服务器端。以下是服务器端代码的大致处理逻辑:

long volatile g_busy = 0; void iocp_thread() { while( GetQueuedCompletionStatus() ) { if( InterlockedCompareExchange( &g_busy, 1, 0 ) != 0 ) WSASend( "服务器忙" ); // 处理命令 ProcessCommand(); WSASend( "应答信息" ); InterlockedExchange( &g_busy, 0 ); } }

其中 ProcessCommand 需要互斥运行(这是简化的逻辑,实际上有很多不同的命令,有些需要互斥,有些可以并行,否则就没必要用完成端口了),并且需要一定的时间才能处理完毕。为了避免多个客户端同时执行命令,导致所有的 iocp 线程都等在那,我把 g_busy 当成了一个锁,第一个线程可以成功进入,其它的都直接向客户端返回“服务器忙”。

程序一直都运行的很好,直到有一天把服务器程序装到了一台双核的机器上。我发现,如果让客户端连续发送命令,即收到上一条命令的应答后立即发送下一条命令,就会随机的返回“服务器忙”,而这时只有一个客户端连接上去,按照我设想的逻辑是不可能出这种情况的。检查了半天代码,没觉得有什么问题,调试吧,又遇到了另一个难题,海森堡的测不准原理起作用了,做的工作太多问题就消失了,做的太少又得不到什么有价值的信息。搞得我很是头疼。

今天再次看这个问题,突然想到:它肯定和线程切换相关,所以我应该记录下每次处理命令的线程的 ID,这样出错时就可以看看上次成功执行命令的那个线程在干什么了。方法正确了,问题也就迎刃而解了,我发现,出问题时,上一个线程的 WSASend 居然还没有返回,也就是说,客户端已经收到应答并发送了下一条命令,服务器端也收到了命令并准备处理,但上一条命令的应答却还没有完全发送完成,难怪出错了!

总结经验教训,感觉自己一开始被两点给误导了,一是实际程序中的 WSARecv/WSASend 藏的比较深,没这么明显,所以没注意到。二是当时粗略检查代码觉得没问题,就把主要精力放在 ProcessCommand 上了,由于我把它里面一段访问数据库的代码注释掉以后,问题就不出了,所以还看了半天 ATL OLEDB 的源码,最后精疲力尽,其它事情又比较多就放弃了。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 148 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    228 引用 • 476 回帖
  • 技术

    到底什么才是技术呢?

    88 引用 • 179 回帖 • 4 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 37 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    201 引用 • 120 回帖 • 2 关注
  • Anytype
    3 引用 • 31 回帖 • 26 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 539 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • 工具

    子曰:“工欲善其事,必先利其器。”

    299 引用 • 764 回帖
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 829 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 119 关注
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 2 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 51 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 51 关注
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖 • 3 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 754 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 37 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 464 关注
  • V2Ray
    1 引用 • 15 回帖 • 3 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    947 引用 • 1460 回帖 • 2 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    45 引用 • 114 回帖 • 172 关注
  • Excel
    31 引用 • 28 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    500 引用 • 1395 回帖 • 243 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    693 引用 • 537 回帖