Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
同时被这些golang问题所迷惑_Go_Concurrency - Fatal编程技术网

同时被这些golang问题所迷惑

同时被这些golang问题所迷惑,go,concurrency,Go,Concurrency,我刚刚在coursera()上完成了“go中的并发性”课程,最后的作业让我很为难。这是我的意见: // 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 i

我刚刚在coursera()上完成了“go中的并发性”课程,最后的作业让我很为难。这是我的意见:

// 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()
    }

}
//1.应该有5位哲学家共用筷子,每对相邻的哲学家共用一根筷子。
//2.每个哲学家只应该吃3次(而不是像我们在讲座中那样无限循环)
//3.哲学家们拿起筷子的顺序是任意的,而不是排在最前面(我们在课堂上就是这么做的)。
//为了吃饭,哲学家必须得到在自己的goroutine中执行的主机的许可。
//5.主人允许不超过2位哲学家同时用餐。
//每个哲学家都有编号,从1到5。
//当哲学家开始吃饭时(在获得必要的锁后),它会自己在一行上打印“开始吃饭”,其中是哲学家的编号。
//当一个哲学家吃完饭(在他解开锁之前),他会自己在一行上打印“吃完”,其中是哲学家的编号。
包干管
进口(
“fmt”
“同步”
)
变量吃=制造(chan int,2)
var mu sync.RWMutex
变量everyoneAte int
var timeseat=make(映射[int]int,5)
型筷子结构{
同步互斥
}
类型结构{
左撇子*筷子
右筷子
}
func alreadyAte(索引int)布尔{
木锁()
延迟mu.Unlock()
如果时间消耗[索引]==3{
返回真值
}
返回错误
}
func(p)eat(索引int){

吃这是哲学家可能吃三次以上的顺序

假设哲学家_1吃了2次

  • 主:获取
    RLock
  • main:reads
    timeseat[1]==2
  • 主要功能:让哲学家在一个单独的餐桌上吃饭
  • 主:释放
    RLock
  • 主:获取
    RLock
  • main:reads
    timeseat[1]==2
  • 主要功能:让哲学家在一个单独的餐桌上再吃一顿
  • 主:释放
    RLock
  • goroutine_1:获取
  • goroutine_1:set
    timeseat[1]=3
  • goroutine_1:释放
  • goroutine_2:获取
  • goroutine_2:set
    timeseat[1]=4