IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    golang的一个线程调度被停止的问题处理

    战魂小筑发表于 2015-01-30 08:25:00
    love 0

    最近发现, 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爱好者加入, 纯技术研讨



    战魂小筑 2015-01-30 16:25 发表评论


沪ICP备19023445号-2号
友情链接