doujuanqi2909 2017-03-06 20:08
浏览 80
已采纳

使用cgo,为什么在golang的时候C输出不“存活”管道?

I'm experimenting with cgo to use C code from golang, but in my little hello-world test, I've ran into something I can't understand or find more information about.

I'm starting with a simple test similar to examples I've found

    package main

    import (
        "fmt"
        "unsafe"
    )

    /*
    #import <stdio.h>
    #import <stdlib.h>
    */
    import "C"

    func main() {
        go2c := "Printed from C.puts"
        var cstr *C.char = C.CString(go2c)
        defer C.free(unsafe.Pointer(cstr))
        C.puts(cstr)
        fmt.Printf("Printed from golang fmt
")
    }

This simple example just echoes strings to stdout from both golang (using fmt.Printf) and raw C (using C.puts) via the basic cgo binding.

When I run this directly in my terminal, I see both lines:

    $ ./main
    Printed from C.puts
    Printed from golang fmt

When I run this but redirect output in any way – pipe to less, shell redirection to a file, etc – I only see golang's output:

    ./main | cat
    Printed from golang fmt

What happens to the C.puts content when piping / redirecting?

Secondary questions: Is this a cgo quirk, or a c standard library quirk I'm not aware of? Is this behaviour documented? How would I go about debugging this on my own (e.g. is there a good/plausible way for me to 'inspect' what FD1 really is in each block?)

Update: If it's relevant, I'm using go version go1.6.2 darwin/amd64.

  • 写回答

2条回答 默认 最新

  • dsomm80482 2017-03-06 20:27
    关注

    This is C behavior you're seeing.

    Go does not buffer stdout, while in C it is usually buffered. When the C library detects stdout is a tty, it may use line buffering, so the additional inserted by puts will cause the output to be displayed.

    You need to flush stdout to ensure you get all the output:

    go2c := "Printed from C.puts"
    var cstr *C.char = C.CString(go2c)
    defer C.free(unsafe.Pointer(cstr))
    C.puts(cstr)
    C.fflush(C.stdout)
    fmt.Printf("Printed from golang fmt
    ")
    

    See also

    Why does printf not flush after the call unless a newline is in the format string?

    Is stdout line buffered, unbuffered or indeterminate by default?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题