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

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

Go程序中g(shù)oroutine的合理使用

Go程序中g(shù)oroutine的合理使用

Go
一只萌萌小番薯 2021-12-07 10:31:27
我的程序有一個(gè)長時(shí)間運(yùn)行的任務(wù)。我有一個(gè)jdIdList太大的列表- 最多1000000項(xiàng)目,所以下面的代碼不起作用。有沒有辦法通過更好地使用 goroutine 來改進(jìn)代碼?似乎我有太多的 goroutine 正在運(yùn)行,這使我的代碼無法運(yùn)行。運(yùn)行的合理數(shù)量的 goroutine 是多少?var wg sync.WaitGroupwg.Add(len(jdIdList))c := make(chan string)// just think jdIdList as [0...1000000]for _, jdId := range jdIdList {    go func(jdId string) {        defer wg.Done()        for _, itemId := range itemIdList {            // following code is doing some computation which consumes much time(you can just replace them with time.Sleep(time.Second * 1)            cvVec, ok := cvVecMap[itemId]            if !ok {                continue            }            jdVec, ok := jdVecMap[jdId]            if !ok {                continue            }            // long time compute            _ = 0.3*computeDist(jdVec.JdPosVec, cvVec.CvPosVec) + 0.7*computeDist(jdVec.JdDescVec, cvVec.CvDescVec)        }        c <- fmt.Sprintf("done %s", jdId)    }(jdId)}go func() {    for resp := range c {        fmt.Println(resp)    }}()
查看完整描述

1 回答

?
繁華開滿天機(jī)

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

看起來您同時(shí)運(yùn)行了太多東西,導(dǎo)致您的計(jì)算機(jī)內(nèi)存不足。


這是您的代碼版本,它使用有限數(shù)量的工作程序 goroutines 而不是您的示例中的一百萬個(gè) goroutines。由于一次只有幾個(gè) goroutine 運(yùn)行,因此在系統(tǒng)開始交換之前,它們每個(gè)都有更多的可用內(nèi)存。確保每個(gè)小計(jì)算所需的內(nèi)存乘以并發(fā) goroutines 的數(shù)量小于您系統(tǒng)中的內(nèi)存,因此如果for jdId := range work循環(huán)內(nèi)的代碼需要少于 1GB 的內(nèi)存,并且您有 4 個(gè)內(nèi)核和至少 4 GB 的 RAM,設(shè)置clvl為4應(yīng)該可以正常工作。


我還刪除了等待組。代碼仍然是正確的,但僅使用通道進(jìn)行同步。通道上的 for 范圍循環(huán)從該通道讀取,直到它關(guān)閉。這就是我們在完成時(shí)告訴工作線程的方式。


https://play.golang.org/p/Sy3i77TJjA


runtime.GOMAXPROCS(runtime.NumCPU()) // not needed on go 1.5 or later

c := make(chan string)

work := make(chan int, 1) // increasing 1 to a higher number will probably increase performance

clvl := 4 // runtime.NumCPU() // simulating having 4 cores, use NumCPU otherwise

var wg sync.WaitGroup

wg.Add(clvl)

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

    go func(i int) {

        for jdId := range work {

            time.Sleep(time.Millisecond * 100)

            c <- fmt.Sprintf("done %d", jdId)

        }

        wg.Done()

    }(i)

}


// give workers something to do

go func() { 

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

        work <- i

    }


    close(work)

}()


// close output channel when all workers are done

go func() { 

    wg.Wait()

    close(c)

}()


count := 0

for resp := range c {

    fmt.Println(resp, count)

    count += 1

}

它在 go playground 上生成了這個(gè)輸出,同時(shí)模擬了四個(gè) CPU 內(nèi)核。


done 1 0

done 0 1

done 3 2

done 2 3

done 5 4

done 4 5

done 7 6

done 6 7

done 9 8

done 8 9

請注意如何不保證排序。該jdId變量保存您想要的值。您應(yīng)該始終使用gorace 檢測器來測試您的并發(fā)程序。


另請注意,如果您使用的是 go 1.4 或更早版本并且尚未將 GOMAXPROCS 環(huán)境變量設(shè)置為內(nèi)核數(shù),則應(yīng)該這樣做,或者添加runtime.GOMAXPROCS(runtime.NumCPU())到程序的開頭。


查看完整回答
反對 回復(fù) 2021-12-07
  • 1 回答
  • 0 關(guān)注
  • 289 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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