亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

goroutine 沒有輸出

goroutine 沒有輸出

Go
慕標琳琳 2021-09-20 20:33:40
當SayHello()按預期執行時,goroutine 不打印任何內容。package mainimport "fmt"func SayHello() {    for i := 0; i < 10 ; i++ {        fmt.Print(i, " ")    }}func main() {    SayHello()    go SayHello()}
查看完整描述

3 回答

?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

當您的main()函數結束時,您的程序也會結束。它不會等待其他 goroutine 完成。


引用Go 語言規范:程序執行:


程序執行首先初始化主包,然后調用函數main。當該函數調用返回時,程序退出。它不會等待其他(非main)goroutine 完成。


有關更多詳細信息,請參閱此答案。


你必須告訴你的main()函數等待SayHello()作為 goroutine 啟動的函數完成。您可以將它們與頻道同步,例如:


func SayHello(done chan int) {

    for i := 0; i < 10; i++ {

        fmt.Print(i, " ")

    }

    if done != nil {

        done <- 0 // Signal that we're done

    }

}


func main() {

    SayHello(nil) // Passing nil: we don't want notification here

    done := make(chan int)

    go SayHello(done)

    <-done // Wait until done signal arrives

}

另一種選擇是通過關閉通道來表示完成:


func SayHello(done chan struct{}) {

    for i := 0; i < 10; i++ {

        fmt.Print(i, " ")

    }

    if done != nil {

        close(done) // Signal that we're done

    }

}


func main() {

    SayHello(nil) // Passing nil: we don't want notification here

    done := make(chan struct{})

    go SayHello(done)

    <-done // A receive from a closed channel returns the zero value immediately

}

筆記:


根據您的編輯/評論:如果您希望 2 個正在運行的SayHello()函數隨機打印“混合”數字:您不能保證觀察到這種行為。再次,有關更多詳細信息,請參閱上述答案。在轉到內存模型只能保證某些事件發生的其他事件之前,你有沒有保證2個并發夠程是如何執行的。


您可能會嘗試使用它,但要知道結果不是確定性的。首先,您必須啟用多個活動 goroutines 才能執行:


runtime.GOMAXPROCS(2)

其次,你必須首先SayHello()作為一個 goroutine啟動,因為你當前的代碼首先SayHello()在主 goroutine 中執行,只有在它完成后才會啟動另一個:


runtime.GOMAXPROCS(2)

done := make(chan struct{})

go SayHello(done) // FIRST START goroutine

SayHello(nil) // And then call SayHello() in the main goroutine

<-done // Wait for completion


查看完整回答
反對 回復 2021-09-20
?
肥皂起泡泡

TA貢獻1829條經驗 獲得超6個贊

或者(對于 icza 的回答)您可以使用WaitGroupfromsync包和匿名函數來避免更改原始SayHello.


package main


import (

    "fmt"

    "sync"

)


func SayHello() {

    for i := 0; i < 10; i++ {

        fmt.Print(i, " ")

    }

}


func main() {

    SayHello()


    var wg sync.WaitGroup

    wg.Add(1)


    go func() {

        defer wg.Done()

        SayHello()

    }()


    wg.Wait()

}

為了同時打印數字,在單獨的例程中運行每個打印語句,如下所示


package main


import (

    "fmt"

    "math/rand"

    "sync"

    "time"

)


func main() {

    var wg sync.WaitGroup


    for i := 0; i < 10; i++ {

        wg.Add(1)

        go func(fnScopeI int) {

            defer wg.Done()


            // next two strings are here just to show routines work simultaneously

            amt := time.Duration(rand.Intn(250))

            time.Sleep(time.Millisecond * amt)


            fmt.Print(fnScopeI, " ")

        }(i)

    }


    wg.Wait()

}


查看完整回答
反對 回復 2021-09-20
?
MM們

TA貢獻1886條經驗 獲得超2個贊

當main函數返回時,Go 程序退出。


一種選擇是使用類似的方法sync.WaitGroup來等待main從main.


另一種方法是調用runtime.Goexit()在main。從godoc:


Goexit 終止調用它的 goroutine。沒有其他 goroutine 受到影響。Goexit 在終止 goroutine 之前運行所有延遲調用。因為 Goexit 不是一個恐慌,這些延遲函數中的任何恢復調用都將返回 nil。


從主協程調用 Goexit 會終止該協程,而不會返回 func main。由于 func main 沒有返回,程序繼續執行其他 goroutine。如果所有其他 goroutine 退出,程序就會崩潰。


這允許 main goroutine 停止執行,而后臺例程繼續執行。例如:


package main


import (

    "fmt"

    "runtime"

    "time"

)


func f() {

    for i := 0; ; i++ {

        fmt.Println(i)

        time.Sleep(10 * time.Millisecond)

    }

}


func main() {

    go f()

    runtime.Goexit()

}

這比在 main 函數中永遠阻塞更干凈,尤其是對于無限的程序。一個缺點是,如果進程的所有 goroutine 都返回或退出(包括主 goroutine),Go 會將其檢測為錯誤和恐慌:


fatal error: no goroutines (main called runtime.Goexit) - deadlock!

為了避免這種情況,至少一個 goroutine 必須os.Exit在它返回之前調用。調用os.Exit(0)立即終止程序并指示它沒有錯誤地這樣做。例如:


package main


import (

    "fmt"

    "os"

    "runtime"

    "time"

)


func f() {

    for i := 0; i < 10; i++ {

        fmt.Println(i)

        time.Sleep(10 * time.Millisecond)

    }

    os.Exit(0)

}


func main() {

    go f()

    runtime.Goexit()

}

查看完整回答
反對 回復 2021-09-20
  • 3 回答
  • 0 關注
  • 437 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號