dongzhang2150 2018-04-26 22:42
浏览 44
已采纳

等待所有执行例程,不阻塞

I have a question about go routines.

My code:

func main() {

    ok := make(chan bool, 1)

    i := 0
    fmt.Println("Starting...")
    for i <= 3 {
        fmt.Println("Loop: ", i)
        go long(ok, i)
        time.Sleep(1 * time.Second)
        i = i + 1

        select {
        case _ = <-ok:
        default:
            fmt.Println("Default")
        }
    }

    fmt.Println("Done...")

}

func long(c chan bool, i int){
    fmt.Println("Inside long: ", i)
    time.Sleep(3 * time.Second)
    fmt.Println("Done with loop: ", i)
    c <- true

}

This gives me output:

Starting...
Loop:  0
Inside long:  0
Default
Loop:  1
Inside long:  1
Default
Loop:  2
Inside long:  2
Done with loop:  0
Loop:  3
Inside long:  3
Done with loop:  1
Done...

Because I use the default in the select, the channel is non blocking. And the main function exits and so do all current routines. I then read about sync and WaitGrops.

func main() {

    ok := make(chan bool, 1)

    var wg sync.WaitGroup

    i := 0
    fmt.Println("Starting...")
    for i <= 3 {
        fmt.Println("Loop: ", i)
        wg.Add(1)
        go long(ok, i)
        time.Sleep(1 * time.Second)
        i = i + 1

        select {
            case _ = <-ok:
            default:
                fmt.Println("Default")
        }
    }

    wg.Wait()
    fmt.Println("Done...")

}

Which gives me:

Starting...
Loop:  0
Inside long:  0
Default
Loop:  1
Inside long:  1
Default
Loop:  2
Inside long:  2
Done with loop:  0
Loop:  3
Inside long:  3
Done with loop:  1
Done with loop:  2
Done with loop:  3

We are now closer to my desired execution which is: The for loop makes all it calls to the function, and then I get the result async. This would be wonderful if it all worked. But an error is generated:

fatal error: all goroutines are asleep - deadlock! 

Why is that and how should I fix it? (Is it possible to fix without knowing how many times wg.Add() will be executed?)

  • 写回答

3条回答 默认 最新

  • dpus81500574 2018-04-26 23:44
    关注

    So, bits' answer removes the channel which fixes your problem.

    The reason the channel is a problem is that your goroutines try to write into it three times and it has a buffer size of one. And your main routine quickly rips off three goroutines and never waits to read the channel because of the default in select. So it never gets read and the goroutines cannot write to it.

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

报告相同问题?

悬赏问题

  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题