我有一个需要在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
}
答案 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()
在每次检查之间等待一段时间。