Golang stdin循环上的CPU使用率过高

时间:2018-03-28 17:18:52

标签: go

我有一个需要在stdin上监听输入的golang应用程序 - 不是作为命令行实用程序而是继续运行和监听。下面的代码,稍微编辑下来,可以工作,但在“空闲”时有很高的CPU负载 - 我不知道为什么 - 也不清楚如何做得更好。所以我需要相同的功能而不需要CPU负载! (这是ejabberd的身份验证处理程序的一部分)

bioIn := bufio.NewReader(os.Stdin)
bioOut := bufio.NewWriter(os.Stdout)

var err error
var success bool
var length uint16
var result uint16

for {
    binary.Read(bioIn, binary.BigEndian, &length)

    buf := make([]byte, length)

    r, _ := bioIn.Read(buf)
    if r == 0 {
        continue
    }

    if err == nil {
        data := strings.Split(string(buf), ":")
        // I have code to handle the incoming data here...
    } else {
        success = false
    }

    length = 2
    binary.Write(bioOut, binary.BigEndian, &length)

    if success != true {
        result = 0
    } else {
        result = 1
    }

    binary.Write(bioOut, binary.BigEndian, &result)
    bioOut.Flush()
}

答案:

我按照建议添加了一个短暂的睡眠,这有一个魅力;不需要很长时间,也不需要对服务提供的身份验证产生明显影响。通过保证传入数据被缓冲,这是完美的解决方案。谢谢大家。

r, _ := bioIn.Read(buf)
    if r == 0 {
        time.Sleep(25 * time.Millisecond)
        continue
}

2 个答案:

答案 0 :(得分:2)

在这部分代码中:

 r, _ := bioIn.Read(buf)
 if r == 0 {
      continue
  }

检查返回值0,表示EOF。即输入流已结束/终止。一旦stdin终止,它就不会回来。所以你在这里有一个无限循环。它会在每次bioIn.Read()返回0的测试中旋转。

除此之外你不能做更多的事情,退出/退出,stdin还没有为你提供更多的数据。

请注意,您的代码也会放弃从bioIn.Read()返回的错误 - 不要这样做,处理错误 - 在这种情况下您会发现原因。

答案 1 :(得分:0)

你有一个紧密的无限循环,它总是会占用操作系统允许的CPU。你总是在检查是否有任何输入和(在你的示例代码中)你永远不会等待新的输入 - 你只是连续轮询stdin以查看是否有任何输入。您应该使用time.Sleep()在每次检查之间等待一段时间。