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

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

識(shí)別戈蘭死鎖。5 哲學(xué)家問(wèn)題

識(shí)別戈蘭死鎖。5 哲學(xué)家問(wèn)題

Go
躍然一笑 2022-09-12 16:04:36
我正在排隊(duì) 大約30%的運(yùn)行都會(huì)發(fā)生這種情況,其余的都完成了,沒(méi)有錯(cuò)誤。我想我使用WaitGroup的方式是錯(cuò)誤的,但不確定我做錯(cuò)了什么。也許有人可以幫助我識(shí)別我的錯(cuò)誤?謝謝!fatal error: all goroutines are asleep - deadlock!wg.Wait()package mainimport (    "fmt"    "math/rand"    "sync"    "time")const (    numOfPhilosophers = 5    numOfMeals = 3    maxEaters = 2)var doOnce sync.Oncefunc main() {    chopsticks := make([]sync.Mutex, 5)    permissionChannel := make(chan bool)    finishEating := make(chan bool)    go permissionFromHost(permissionChannel,finishEating)    var wg sync.WaitGroup    wg.Add(numOfPhilosophers)    for i:=1 ; i<=numOfPhilosophers ; i++ {        go eat(i, chopsticks[i-1], chopsticks[i%numOfPhilosophers], &wg, permissionChannel, finishEating)    }    wg.Wait()}func eat(philosopherId int, left sync.Mutex, right sync.Mutex, wg *sync.WaitGroup, permissionChannel <-chan bool, finishEatingChannel chan<- bool) {    defer wg.Done()    for i:=1 ; i<=numOfMeals ; i++ {        //lock chopsticks in random order        if RandBool() {            left.Lock()            right.Lock()        } else {            right.Lock()            left.Lock()        }        fmt.Printf("waiting for permission from host %d\n",philosopherId)        <-permissionChannel        fmt.Printf("starting to eat %d (time %d)\n", philosopherId, i)        fmt.Printf("finish to eat %d (time %d)\n", philosopherId, i)        //release chopsticks        left.Unlock()        right.Unlock()        //let host know I am done eating        finishEatingChannel<-true    }}func permissionFromHost(permissionChannel chan<-bool, finishEating <-chan bool) {    ctr := 0    for {        select {        case <-finishEating:            ctr--        default:            if ctr<maxEaters {                ctr++                permissionChannel<-true            }        }    }}func RandBool() bool {    rand.Seed(time.Now().UnixNano())    return rand.Intn(2) == 1}編輯1:我修復(fù)了通過(guò)引用傳遞的互斥體。它沒(méi)有解決問(wèn)題。編輯2:我試圖使用緩沖通道,使其工作permissionChannel:=make(chan bool, numOfPhilosophers)編輯3:也@Jaroslaw例子使它工作
查看完整描述

2 回答

?
蠱毒傳說(shuō)

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

最后一個(gè) goroutine 不會(huì)退出,當(dāng)它寫入通道時(shí),它將在最后一次迭代中被阻止,因?yàn)樗鼪](méi)有消費(fèi)者。沒(méi)有消費(fèi)者的原因是函數(shù)中的選擇情況正在寫入,但沒(méi)有消費(fèi)者,因?yàn)樗诘却蛔x取,所以我們有一個(gè)死鎖。finishEatingChannelfinishEatingChannelpermissionFromHostpermissionChannel<-truepermissionChannel

您可以使權(quán)限從主機(jī)通道緩沖,它將解決此問(wèn)題。

您的代碼中還有一個(gè)錯(cuò)誤,您正在按值傳遞互斥體,這是不允許的


查看完整回答
反對(duì) 回復(fù) 2022-09-12
?
慕后森

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

該命令說(shuō)go vet


./main.go:26:13: call of eat copies lock value: sync.Mutex

./main.go:26:30: call of eat copies lock value: sync.Mutex

./main.go:31:34: eat passes lock by value: sync.Mutex

./main.go:31:52: eat passes lock by value: sync.Mutex

另一個(gè)問(wèn)題是,有時(shí) goroutines(哲學(xué)家)在嘗試發(fā)送確認(rèn)時(shí)會(huì)被阻止,因?yàn)樨?fù)責(zé)從此無(wú)緩沖通道讀取數(shù)據(jù)的 goroutine(主機(jī))正忙于嘗試發(fā)送權(quán)限。以下是代碼的確切部分:finishEatingChannel


            if ctr<maxEaters {

                ctr++

                // This goroutine stucks since the last philosopher is not reading from permissionChannel.

                // Philosopher is not reading from this channel at is busy trying to write finishEating channel which is not read by this goroutine.

                // Thus the deadlock happens.

                permissionChannel<-true 

            }

死鎖是100%可重復(fù)的,當(dāng)只剩下一個(gè)哲學(xué)家需要吃兩次飯時(shí)。


固定版本的代碼:


package main


import (

    "fmt"

    "math/rand"

    "sync"

    "time"

)


const (

    numOfPhilosophers = 5

    numOfMeals        = 3

    maxEaters         = 2

)


func main() {

    chopsticks := make([]sync.Mutex, 5)

    permissionChannel := make(chan bool)

    finishEating := make(chan bool)

    go permissionFromHost(permissionChannel, finishEating)

    var wg sync.WaitGroup

    wg.Add(numOfPhilosophers)

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

        go eat(i, &chopsticks[i-1], &chopsticks[i%numOfPhilosophers], &wg, permissionChannel, finishEating)

    }

    wg.Wait()

}


func eat(philosopherId int, left *sync.Mutex, right *sync.Mutex, wg *sync.WaitGroup, permissionChannel <-chan bool, finishEatingChannel chan<- bool) {

    defer wg.Done()

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

        //lock chopsticks in random order

        if RandBool() {

            left.Lock()

            right.Lock()

        } else {

            right.Lock()

            left.Lock()

        }


        fmt.Printf("waiting for permission from host %d\n", philosopherId)

        <-permissionChannel


        fmt.Printf("starting to eat %d (time %d)\n", philosopherId, i)

        fmt.Printf("finish to eat %d (time %d)\n", philosopherId, i)

        //release chopsticks

        left.Unlock()

        right.Unlock()


        //let host know I am done eating

        finishEatingChannel <- true

    }

}


func permissionFromHost(permissionChannel chan<- bool, finishEating <-chan bool) {

    ctr := 0

    for {

        if ctr < maxEaters {

            select {

            case <-finishEating:

                ctr--

            case permissionChannel <- true:

                ctr++

            }

        } else {

            <-finishEating

            ctr--

        }

    }

}


func RandBool() bool {

    rand.Seed(time.Now().UnixNano())

    return rand.Intn(2) == 1

}


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

添加回答

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