首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对这些与并发性有关的问题感到困惑

对这些与并发性有关的问题感到困惑
EN

Stack Overflow用户
提问于 2018-11-22 20:45:08
回答 1查看 392关注 0票数 0

我刚刚完成了课程中的“并行围棋”课程(https://www.coursera.org/learn/golang-concurrency/),我真的很难完成最后的作业。这是我的意见书:

代码语言:javascript
复制
// 1.There should be 5 philosophers sharing chopsticks, with one chopstick between each adjacent pair of philosophers.
// 2.Each philosopher should eat only 3 times (not in an infinite loop as we did in lecture)
// 3.The philosophers pick up the chopsticks in any order, not lowest-numbered first (which we did in lecture).
// 4.In order to eat, a philosopher must get permission from a host which executes in its own goroutine.
// 5.The host allows no more than 2 philosophers to eat concurrently.
// 6.Each philosopher is numbered, 1 through 5.
// 7.When a philosopher starts eating (after it has obtained necessary locks) it prints “starting to eat <number>” on a line by itself, where <number> is the number of the philosopher.
// 8.When a philosopher finishes eating (before it has released its locks) it prints “finishing eating <number>” on a line by itself, where <number> is the number of the philosopher.
package main

import (
    "fmt"
    "sync"
)

var eating = make(chan int, 2)

var mu sync.RWMutex
var everyoneAte int
var timesEaten = make(map[int]int, 5)

type chopstick struct {
    sync.Mutex
}

type philosopher struct {
    leftCs  *chopstick
    rightCs *chopstick
}

func alreadyAte(index int) bool {
    mu.Lock()
    defer mu.Unlock()
    if timesEaten[index] == 3 {
        return true
    }
    return false
}
func (p philosopher) eat(index int) {

    eating <- 1

    p.leftCs.Lock()
    p.rightCs.Lock()

    fmt.Printf("Starting to eat %v\n", index)
    fmt.Printf("Finishing eating %v\n", index)
    mu.Lock()
    timesEaten[index]++
    if timesEaten[index] == 3 {
        everyoneAte++
    }
    mu.Unlock()
    p.rightCs.Unlock()
    p.leftCs.Unlock()
    <-eating
}

func main() {
    count := 5
    chopsticks := make([]*chopstick, count)
    for i := 0; i < count; i++ {
        chopsticks[i] = &chopstick{}
    }

    philosophers := make([]*philosopher, count)
    for i := 0; i < count; i++ {
        philosophers[i] = &philosopher{
            leftCs:  chopsticks[i],
            rightCs: chopsticks[(i+1)%count],
        }
    }
    for {
        mu.RLock()
        if everyoneAte == count {
            return
        }
        for i := 0; i < count; i++ {
            if timesEaten[i] == 3 {
                continue
            }
            go philosophers[i].eat(i + 1)
        }
        mu.RUnlock()
    }

}

我不知道如何实现#4,所以我只使用了一个缓冲通道而不是‍♂️

我不明白为什么有些哲学家回来后吃了超过3次

如果每个人都有这些问题的答案,我将不胜感激。我已经提交了作业。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-23 03:46:07

以下是哲学家吃三次以上的顺序。

假设philosopher_1吃了两次

  1. 主营:收购RLock
  2. 主:读取timesEaten[1] == 2
  3. 主语:让philosopher_1在单独的goroutine_1上吃东西
  4. 主要:发布RLock
  5. 主营:收购RLock
  6. 主:读取timesEaten[1] == 2
  7. main:让philosopher_1在单独的goroutine_2上再吃一次
  8. 主要:发布RLock
  9. goroutine_1:收购Lock
  10. goroutine_1:设置timesEaten[1] = 3
  11. goroutine_1:发布Lock
  12. goroutine_2:收购Lock
  13. goroutine_2:设置timesEaten[1] = 4 <-- philosopher_1吃了3次以上
  14. goroutine_2:发布Lock
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53437791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档