第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Golang:為什么 os.Exit 在 goroutines 中不起作用

Golang:為什么 os.Exit 在 goroutines 中不起作用

Go
喵喵時(shí)光機(jī) 2021-12-07 14:20:22
我有一個(gè)算法非常簡(jiǎn)單的研究程序。當(dāng)成功到來時(shí),goroutine 應(yīng)該通過 os.Exit(0) 關(guān)閉(結(jié)束)。我等一天,兩天……什么?:)這是簡(jiǎn)單的代碼package mainimport "os"func main() {    for {        go func() { os.Exit(0) }()    }}我的問題:為什么 os.Exit 不終止 goroutine?終止(停止)goroutine 執(zhí)行的正確方法是什么?游樂場(chǎng):http : //play.golang.org/p/GAeOI-1Ksc
查看完整描述

3 回答

?
呼如林

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超3個(gè)贊

您遇到了 Go 調(diào)度程序的一個(gè)棘手問題。答案是這os.Exit 確實(shí)會(huì)導(dǎo)致整個(gè)進(jìn)程退出,但是按照您的方式,goroutines 從未運(yùn)行。


可能發(fā)生的情況是 for 循環(huán)不斷向可用 goroutine 列表中添加新的 goroutine,但是由于整個(gè)進(jìn)程僅在一個(gè) OS 線程中運(yùn)行,因此 Go 調(diào)度程序從未真正安排過不同的 goroutine,只是繼續(xù)運(yùn)行它for 循環(huán)而無需運(yùn)行您生成的任何 goroutine。試試這個(gè):


package main


import "os"


func main() {

    for {

        go func() { os.Exit(0) }()

        func() {}()

    }

}

如果您在 Go Playground 上運(yùn)行它,它應(yīng)該可以工作(實(shí)際上,這是一個(gè)鏈接)。


好的,上面的代碼可以運(yùn)行而你的代碼不運(yùn)行的事實(shí)應(yīng)該很神秘。這樣做的原因是 Go 調(diào)度程序?qū)嶋H上是非搶占的。這意味著除非給定的 goroutine 自愿決定給調(diào)度程序運(yùn)行其他東西的選項(xiàng),否則其他任何東西都不會(huì)運(yùn)行。


顯然,您從未編寫過包含讓調(diào)度程序有機(jī)會(huì)運(yùn)行的命令的代碼。發(fā)生的情況是,當(dāng)您的代碼被編譯時(shí),Go 編譯器會(huì)自動(dòng)將這些插入到您的代碼中。這是上述代碼為何起作用的關(guān)鍵:goroutine 可能決定運(yùn)行調(diào)度程序的時(shí)間之一是調(diào)用函數(shù)時(shí)。因此,通過添加func() {}()調(diào)用(顯然什么都不做),我們?cè)试S編譯器添加對(duì)調(diào)度程序的調(diào)用,讓這段代碼有機(jī)會(huì)調(diào)度不同的 goroutine。因此,產(chǎn)生的 goroutine 之一運(yùn)行,調(diào)用os.Exit,然后進(jìn)程退出。


編輯:在編譯器內(nèi)聯(lián)調(diào)用的情況下,函數(shù)調(diào)用本身可能是不夠的(或者,在這種情況下,因?yàn)樗裁炊疾蛔龆耆珓h除它)。runtime.Gosched(),另一方面,保證工作。


查看完整回答
反對(duì) 回復(fù) 2021-12-07
?
拉莫斯之舞

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊

您可以通過從函數(shù)返回來終止 goroutine。如果需要確保 goroutine 運(yùn)行完成,則需要等待 goroutine 完成。這通常是通過sync.WaitGroup, 或通過通道同步 goroutine 來完成的。


在您的示例中,您首先需要確保不可能產(chǎn)生無限數(shù)量的 goroutine。因?yàn)閙ain新的 goroutine之間沒有同步點(diǎn),所以不能保證os.Exit在主循環(huán)運(yùn)行時(shí)它們中的任何一個(gè)都會(huì)執(zhí)行調(diào)用。


等待任意數(shù)量的 goroutine 完成的通常方法是使用 a sync.WaitGroup,這將確保它們?cè)趍ain退出之前都已執(zhí)行。


wg := sync.WaitGroup{}

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

    wg.Add(1)

    go func() { defer wg.Done() }()

}


wg.Wait()

fmt.Println("done")


查看完整回答
反對(duì) 回復(fù) 2021-12-07
?
慕村225694

TA貢獻(xiàn)1880條經(jīng)驗(yàn) 獲得超4個(gè)贊

實(shí)施死手或終止開關(guān)


package main


import (

        "fmt"

        "time"

        "os"

)


const maxNoTickle = 50          // will bail out after this many no tickles

const maxWorking = 20           // pretendWork() will tickle this many times

const deadTicks = 250           // milliseconds for deadHand() to check for tickles

const reportTickles = 4         // consecutive tickles or no tickles to print something


var (

        tickleMe bool           // tell deadHand() we're still alive

        countNoTickle int       // consecutive no tickles

        countGotTickle int      // consecutive tickles

)


/**

*       deadHand() - callback to kill program if nobody checks in after some period

*/

func deadHand() {

        if !tickleMe {

                countNoTickle++

                countGotTickle = 0

                if countNoTickle > maxNoTickle {

                        fmt.Println("No tickle max time reached. Bailing out!")

                        // panic("No real panic. Just checking stack")

                        os.Exit(0)

                }

                if countNoTickle % reportTickles == 0 {

                        // print dot for consecutive no tickles

                        fmt.Printf(".")

                }

        } else {

                countNoTickle = 0

                countGotTickle++

                tickleMe = false        // FIXME: might have race condition here

                if countGotTickle % reportTickles == 0 {

                        // print tilda for consecutive tickles

                        fmt.Printf("~")

                }

        }

        // call ourselves again

        time.AfterFunc(deadTicks * time.Millisecond, deadHand)

}


/**

*       init() - required to start deadHand

*/

func init() {

        time.AfterFunc(250 * time.Millisecond, deadHand)

        tickleMe = true

}


/**

*       pretendWork() - your stuff that does its thing

*/

func pretendWork() {

        for count := 0; count < maxWorking; count++ {

                tickleMe = true // FIXME: might have race condition here

                // print W pretending to be busy

                fmt.Printf("W")

                time.Sleep(100 * time.Millisecond)

        }

}


func main() {

        go workTillDone()

        for {

                // oops, program went loop-d-loopy

        }

}


查看完整回答
反對(duì) 回復(fù) 2021-12-07
  • 3 回答
  • 0 關(guān)注
  • 271 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)