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

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

如何跨 goroutines 共享地圖

如何跨 goroutines 共享地圖

Go
犯罪嫌疑人X 2023-04-04 14:40:40
我正在嘗試在 Go 中編寫(xiě)一個(gè)通知結(jié)構(gòu),它將保存一系列鍵及其各自的值,并且如果值低于閾值將觸發(fā)通知。當(dāng)?shù)谝粋€(gè)樣本低于閾值時(shí),通知應(yīng)該只觸發(fā)一次,并且低于該值的其他樣本不應(yīng)再次觸發(fā),直到值升至閾值以上。例如,假設(shè)我的閾值是 10,我發(fā)送了 15、14、11、10、... 9 的樣本。發(fā)送 9 后,應(yīng)觸發(fā)通知。8、7、4 的進(jìn)一步樣本不應(yīng)造成任何影響。以下樣本如 5、6、7、9、10、11、14、30 不應(yīng)執(zhí)行任何操作。一旦樣本再次低于 10:30、20、15、10、7... 必須發(fā)送另一個(gè)通知。當(dāng)多個(gè) goroutines 操縱我的結(jié)構(gòu)時(shí),我遇到了問(wèn)題。我嘗試使用 sync.Mutex 進(jìn)行同步,還使用了 sync.Map,但沒(méi)有成功。我覺(jué)得某處有參考副本或緩存,但我對(duì) Go 太陌生了,無(wú)法找到問(wèn)題所在。為此,我創(chuàng)建了一個(gè)這樣的結(jié)構(gòu):type Notifier interface {    Send(message string)}type NotificationBoard struct {    mutex    sync.Mutex    Last     sync.Map    notifier Notifier}func (n *NotificationBoard) Init(notifier Notifier) {    n.notifier = notifier}// NotifyLess ...func (n *NotificationBoard) NotifyLess(key string, value, threshold float64) {    n.mutex.Lock()    defer n.mutex.Unlock()    if value >= threshold {        fmt.Printf("NotificationBoard.NotifyLess %v (value >= threshold): %v >= %v\n", key, value, threshold)        n.Last.Store(key, value)        return    }    // value < threshold    if last, found := n.Last.Load(key); found == true {        fmt.Printf("NotificationBoard.NotifyLess %v (value < threshold): %v < %v : found %v\n", key, value, threshold, last)        if last.(float64) >= threshold { // first trigger            n.notifier.Send(fmt.Sprintf("%s < %v (%v)", key, threshold, value))        }    } else {        fmt.Printf("NotificationBoard.NotifyLess %v (value < threshold): %v < %v : not found\n", key, value, threshold)        // not found, started board as less        n.notifier.Send(fmt.Sprintf("%s < %v (%v)", key, threshold, value))    }    n.Last.Store(key, value)    return}我知道使用 sync.Mutex 或 sync.Map 應(yīng)該就足夠了,但上面的代碼兩者都有,因?yàn)樗俏耶?dāng)前的(損壞的)版本。為了測(cè)試,我設(shè)置了以下代碼:type dummy struct{}func (d *dummy) Send(message string) {    fmt.Println("--------------> notifying", message)}func newBoard() *NotificationBoard {    notificationBoard := &NotificationBoard{}    notificationBoard.Init(&dummy{})    return notificationBoard}
查看完整描述

2 回答

?
嚕嚕噠

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

在這里簡(jiǎn)化邏輯的一種方法可能是運(yùn)行一個(gè)修改地圖的 goroutine。然后,它可以監(jiān)聽(tīng)通道上的新值(因?yàn)槿绻错樞蛱幚碇祽?yīng)該沒(méi)問(wèn)題)。您需要小心知道您的 goroutine 何時(shí)返回以確保它不會(huì)泄漏。一般來(lái)說(shuō),你不應(yīng)該在 goroutines 之間共享數(shù)據(jù),你應(yīng)該使用通道在 goroutines 之間進(jìn)行通信。

這是一個(gè)示例,說(shuō)明如何使用通道而不是共享內(nèi)存(游樂(lè)場(chǎng)版本)來(lái)實(shí)現(xiàn)此類應(yīng)用程序。

package main


import (

? ? "fmt"

? ? "sync"

)


type value struct {

? ? key? ? ? ?string

? ? value? ? ?float64

? ? threshold float64

}


func main() {

? ? b := board{

? ? ? ? last: map[string]float64{},

? ? }

? ? c := b.start()

? ? wg := sync.WaitGroup{}

? ? for i := 0; i < 30; i++ {

? ? ? ? wg.Add(1)

? ? ? ? go func(i int) {

? ? ? ? ? ? for j := 15.0; j > 5; j-- {

? ? ? ? ? ? ? ? c <- value{"k1", j + float64(i+1)/100, 10}

? ? ? ? ? ? }

? ? ? ? ? ? wg.Done()

? ? ? ? }(i)

? ? }

? ? wg.Wait()

? ? close(c)

}


type board struct {

? ? last map[string]float64

}


func (b *board) start() chan<- value {

? ? c := make(chan value)

? ? go func() {

? ? ? ? for v := range c {

? ? ? ? ? ? b.notify(v)

? ? ? ? }

? ? }()

? ? return c

}


func (b *board) notify(v value) {

? ? if l, ok := b.last[v.key]; !ok || l >= v.threshold {

? ? ? ? if v.value < v.threshold {

? ? ? ? ? ? fmt.Printf("%s < %v (%v)\n", v.key, v.threshold, v.value)

? ? ? ? }

? ? }

? ? b.last[v.key] = v.value

}


查看完整回答
反對(duì) 回復(fù) 2023-04-04
?
當(dāng)年話下

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

我認(rèn)為您在設(shè)置此類跟蹤器時(shí)需要設(shè)置標(biāo)志,一個(gè)用于價(jià)值上升,另一個(gè)用于價(jià)值下降。我實(shí)施了一個(gè)


package main


import (

    "fmt"

    "sync"

)


const (

    threshold      int = 10

    upperThreshold int = 20

)


var mu sync.Mutex

var downwatch bool

var upwatch bool


func main() {

    var tracker int = 10

    var temp int = 1

    var sign int = 1

    for i := 1; i < 20; i++ {

        sign = sign * -1

        temp = temp + i

        go UpdateTracker(&tracker, temp*sign)

    }


    for {

    }

    return

}

func SetDownWatch() {

    downwatch = true

}

func SetUpWatch() {

    upwatch = true

}

func UnSetDownWatch() {

    downwatch = false

}

func UnSetUpWatch() {

    upwatch = false

}


func UpdateTracker(tracker *int, val int) {

    mu.Lock()

    defer mu.Unlock()

    if !(upwatch || downwatch) {

        if (*tracker)+val < threshold {

            NotifyOnDrop()

            SetDownWatch()

        }

        if (*tracker + val) > upperThreshold {

            NotifyOnRise()

            SetUpWatch()

        }


    }

    if (*tracker)+val < threshold && upwatch {

        NotifyOnDrop()

        SetDownWatch()

        UnSetUpWatch()

    }


    if (*tracker+val) > upperThreshold && downwatch {

        NotifyOnRise()

        SetUpWatch()

        UnSetDownWatch()

    }


    *tracker = (*tracker) + val

    fmt.Println((*tracker))

    return

}


func NotifyOnDrop() {

    fmt.Println("dropped")

    return

}


func NotifyOnRise() {

    fmt.Println("rose")

    return

}

updateTracker當(dāng)值超過(guò)設(shè)置的閾值時(shí),作為 go 例程運(yùn)行并打印到控制臺(tái)。我認(rèn)為這就是您正在尋找的功能,這里缺少的是Last.Store我認(rèn)為是您的代碼自定義的功能。我相信還有其他方法可以處理這個(gè)問(wèn)題。這對(duì)我來(lái)說(shuō)似乎很簡(jiǎn)單。


查看完整回答
反對(duì) 回復(fù) 2023-04-04
  • 2 回答
  • 0 關(guān)注
  • 171 瀏覽
慕課專欄
更多

添加回答

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