doublestar2014 2015-03-03 15:36
浏览 62
已采纳

去调度程序和CGO:请解释这种行为差异吗?

I'd like to know the implementation reason for this:

package main

func main() {
    c := make(chan struct{})

    go func() {
        print("a")
        for {
        }
    }()

    go func() {
        print("b")
        for {
        }
    }()

    go func() {
        print("c")
        c <- struct{}{}
        for {
        }
    }()

    <-c
}

❯❯❯ GOMAXPROCS=2 go run sample1.go                                    
ab  <--- blocks.

package main

// static void loop() { for(;;); }
import "C"

func main() {
    c := make(chan struct{})

    go func() {
        print("a")
        C.loop()
        print("x")
    }()

    go func() {
        print("b")
        C.loop()
        print("y")
    }()

    go func() {
        print("c")
        c <- struct{}{}
        C.loop()
        print("z")
    }()

    <-c
}

❯❯❯ GOMAXPROCS=2 go run sample2.go                                    
abc  <--- ends gracefully.

More specifically I mean how the C tight loop differs from the Go one in the context of go routine scheduling. And even though the C tight loops should be being abruptly terminated at the end of the Go program, I'd like to know whether it's safe to rely on this behavior to start C tasks without blocking the Go program.

  • 写回答

1条回答 默认 最新

  • doushi9780 2015-03-03 15:43
    关注

    The runtime can't preempt a true busy-loop. A CPU intensive loop with no scheduling points has to be in it's own thread for other goroutines to be able to run. Function calls and channel send or receive operations all yield. Network IO is scheduled asynchronously, and file IO gets its own thread.

    Generally setting GOMAXPROCS > 1 is sufficient, but since you have 3 of these loops, and only 2 threads, the scheduler is still blocked. If you have a valid CPU intensive loop that is making it difficult to schedule goroutines, you can call runtime.GoSched() periodically to yield to the scheduler. In the real world, the only place where this generally maters is a programming error where you have an empty loop.

    All cgo calls happen in their own threads outside of the go runtime, so those loops have no effect on the main loop, other than wasting CPU.

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

报告相同问题?

悬赏问题

  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程