duanpenpan5796 2015-01-30 15:08
浏览 87
已采纳

在Go中读取命名管道时100%CPU使用率

I have a short Go program which reads from a named pipe and processes each line as an external process writes to the pipe. The named pipe is created before the program runs using mkfifo.

The process is taking up 100% of the CPU when waiting for a new line from the named pipe, even when it's not doing any processing. It's running on Ubuntu 14.04. Any ideas?

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)

awaitingExit := false

var wg sync.WaitGroup

go func() {
    for sig := range c {
        awaitingExit = true

        // wait for goroutines to finish processing new lines
        wg.Wait()
        os.Exit(1)
    }
}()

file, err := os.OpenFile("file.fifo", os.O_RDONLY, os.ModeNamedPipe)

defer file.Close()

if err != nil {
    log.Fatal(err)
}

reader := bufio.NewReader(file)

// infinite loop
for {
    line, _, _ := reader.ReadLine()

    // stop handling new lines if we're waiting to exit
    if !awaitingExit && len(line) > 0 {
        wg.Add(1)

        go func(uploadLog string) {
            defer wg.Done()
            handleNewLine(uploadLog)
        }(string(line))
    }
}

func handleNewLine(line string) {
    ....
}
  • 写回答

1条回答 默认 最新

  • dqpfl2508589 2015-01-30 15:18
    关注

    Your "infinite loop" is really infinite: you never exit it or jump out of it.

    It contains an if:

    // stop handling new lines if we're waiting to exit
    if !awaitingExit && len(line) > 0 {
        // code omitted
    }
    

    But if the condition is false, you're still not getting out of the for loop, just continue with another iteration. Once you reach the end of reader, this loop will consume 100% of a core because after that it will not wait for anything just trying to read (which will immediately return EOF) and checking the awaitExit variable and doing these 2 steps again.

    You either need to add condition to the for loop to exit sometime, or use a break statement to break out of it.

    Altered for loop with a condition:

    for !awaitingExit {
    }
    

    Altered for with a break statement:

    for {
        if awaitingExit {
            break
        }
        // code omitted
    }
    

    Note: if awaitingExit variable is changed by another goroutine, you need proper synchronization, or better, use channels for exit signalling.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器