最近发现, golang写的游戏服务器, 在非调试状态下, 一切正常, 但是在挂接gdb调试时, 无法收到网络消息. 打了很多日志, 发现, 只要有goroutine的地方, 都没有切换进入. 
 回想了下, goroutine的调度规则: 1.4之前, 在碰到syscall时, goroutine会被调度并处理. 1.4后, 只要有函数调用时, 均会进行一次调度. 密度比以前增加了, 更加接近真线程的处理. 
 根据这个原理, 问题应该出现在服务器底层没有给系统提供调度机会的点上. 我们的服务器通过一个bool型的chan进行阻塞, 让服务器维持阻塞进行消息处理不退出. 但是最近为了在windows下提供命令行支持, 增加了一些代码, 如下
    1:  func WaitForExit() {   2:   
   3:      if len(peerMap) == 0 {   4:          log.Println("no peer running, exit!")   5:          return
   6:      }
   7:   
   8:      // 命令行功能只在windows下启用
   9:      if runtime.GOOS == "windows" {  10:          reader := bufio.NewReader(os.Stdin)
  11:   
  12:          var running bool = true
  13:   
  14:          go func() {  15:              select {  16:              case <-exitChan:
  17:                  running = false
  18:              }
  19:          }()
  20:   
  21:          for running {  22:              data, _, _ := reader.ReadLine()
  23:              command := string(data)
  24:   
  25:              dispatchConsoleCommand(command)
  26:          }
  27:      } else {  28:          // Linux环境
  29:          <-exitChan
  30:      }
  31:   
  32:  }
我暂时屏蔽了新加的这套功能, 维持<-exitChan, 问题马上解决
结合前面的猜测, 我估计在reader.ReadLine()函数内, 没有给底层提供调度的机会, 导致其他goroutine无法运行, 造成服务器卡死
技术讨论群:  309800774 欢迎golang爱好者加入, 纯技术研讨