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

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

無(wú)法同時(shí)使用 goroutines 來查找最大值,直到上下文被取消

無(wú)法同時(shí)使用 goroutines 來查找最大值,直到上下文被取消

Go
喵喵時(shí)光機(jī) 2022-09-05 17:44:54
我已經(jīng)成功地做了一個(gè)同步解決方案,沒有對(duì)調(diào)用的干擾。findMaxcomputepackage mainimport (    "context"    "fmt"    "math/rand"    "time")func findMax(ctx context.Context, concurrency int) uint64 {    var (        max uint64 = 0        num uint64 = 0    )    for i := 0; i < concurrency; i++ {        num = compute()        if num > max {            max = num        }    }    return max}func compute() uint64 {    // NOTE: This is a MOCK implementation of the blocking operation.        time.Sleep(time.Duration(rand.Int63n(100)) * time.Millisecond)    return rand.Uint64()}func main() {    maxDuration := 2 * time.Second    concurrency := 10    ctx, cancel := context.WithTimeout(context.Background(), maxDuration)    defer cancel()    max := findMax(ctx, concurrency)    fmt.Println(max)}https://play.golang.org/p/lYXRNTDtNCI當(dāng)我嘗試使用 goroutines 來重復(fù)調(diào)用函數(shù)時(shí)使用盡可能多的 goroutines,直到上下文被調(diào)用方函數(shù)取消。我每次都得到0,而不是灌漿計(jì)算函數(shù)調(diào)用的預(yù)期最大值。我嘗試了不同的方法來做到這一點(diǎn),并且大部分時(shí)間都陷入僵局。findMaxcomputectxmainpackage mainimport (    "context"    "fmt"    "math/rand"    "time")func findMax(ctx context.Context, concurrency int) uint64 {    var (        max uint64 = 0        num uint64 = 0    )    for i := 0; i < concurrency; i++ {        select {        case <- ctx.Done():            return max        default:            go func() {                num = compute()                if num > max {                    max = num                }            }()        }    }    return max}func compute() uint64 {    // NOTE: This is a MOCK implementation of the blocking operation.        time.Sleep(time.Duration(rand.Int63n(100)) * time.Millisecond)    return rand.Uint64()}func main() {    maxDuration := 2 * time.Second    concurrency := 10    ctx, cancel := context.WithTimeout(context.Background(), maxDuration)    defer cancel()    max := findMax(ctx, concurrency)    fmt.Println(max)}https://play.golang.org/p/3fFFq2xlXAE
查看完整描述

1 回答

?
元芳怎么了

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

您的程序存在多個(gè)問題:

  1. 您正在生成多個(gè)對(duì)共享變量進(jìn)行操作的goroutine,即,并導(dǎo)致數(shù)據(jù)競(jìng)爭(zhēng),因?yàn)樗鼈儾皇鼙Wo(hù)(例如,受Mutex保護(hù))。maxnum

  2. 這里由每個(gè) worker goroutine 修改,但它應(yīng)該是 worker 的本地,否則計(jì)算的數(shù)據(jù)可能會(huì)丟失(例如,一個(gè) worker goroutine 計(jì)算了一個(gè)結(jié)果并將其存儲(chǔ)在 num 中,但緊隨其后,第二個(gè) worker 計(jì)算并替換了 num 的值)。num

 num = compute // Should be "num := compute"
  1. 您不會(huì)等待每個(gè) goroutine 完成計(jì)算,這可能會(huì)導(dǎo)致不正確的結(jié)果,因?yàn)榧词股舷挛奈慈∠?,也不?huì)考慮每個(gè)工作線程計(jì)算。使用 或 渠道來解決此問題。sync.WaitGroup

下面是一個(gè)示例程序,可解決代碼中的大多數(shù)問題:

package main


import (

    "context"

    "fmt"

    "math/rand"

    "sync"

    "time"

)


type result struct {

    sync.RWMutex

    max uint64

}


func findMax(ctx context.Context, workers int) uint64 {

    var (

        res = result{}

        wg  = sync.WaitGroup{}

    )


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

        select {

        case <-ctx.Done():

            // RLock to read res.max

            res.RLock()

            ret := res.max

            res.RUnlock()

            return ret

        default:

            wg.Add(1)

            go func() {

                defer wg.Done()

                num := compute()


                // Lock so that read from res.max and write

                // to res.max is safe. Else, data race could

                // occur.

                res.Lock()

                if num > res.max {

                    res.max = num

                }

                res.Unlock()

            }()

        }

    }


    // Wait for all the goroutine to finish work i.e., all

    // workers are done computing and updating the max.

    wg.Wait()


    return res.max

}


func compute() uint64 {

    rnd := rand.Int63n(100)

    time.Sleep(time.Duration(rnd) * time.Millisecond)

    return rand.Uint64()

}


func main() {

    maxDuration := 2 * time.Second

    concurrency := 10


    ctx, cancel := context.WithTimeout(context.Background(), maxDuration)

    defer cancel()


    fmt.Println(findMax(ctx, concurrency))

}

正如@Brits在注釋中指出的那樣,當(dāng)上下文被取消時(shí),請(qǐng)確保停止那些工作線程goroutines以停止處理(如果可能的話),因?yàn)樗辉傩枰恕?/p>


查看完整回答
反對(duì) 回復(fù) 2022-09-05
  • 1 回答
  • 0 關(guān)注
  • 94 瀏覽
慕課專欄
更多

添加回答

舉報(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)