Golang中如何解决哲学家就餐问题
Golang中如何解决哲学家就餐问题 我正在研究哲学家就餐问题的程序
应该有5位哲学家共享筷子,每对相邻哲学家之间有一根筷子。 每位哲学家只能吃3次 哲学家可以按任意顺序拿起筷子,不一定先拿编号最小的 要开始用餐,哲学家必须从在自己例程中运行的主机获得许可。 主机不允许超过2位哲学家同时用餐。 每位哲学家的编号从1到5。 当哲学家开始用餐时(在获得必要的锁之后),打印"开始用餐 <编号>",其中<编号>是哲学家的编号。 当哲学家结束用餐时(在释放锁之前),打印"结束用餐 <编号>",其中<编号>是哲学家的编号。
type ChopS struct{ sync.Mutex }
type Philo struct {
leftCS, rightCS * ChopS
}
//Eat
func (p Philo) eat() {
for {
p.leftCS.Lock()
p.rightCS.Lock()
fmt.Println("eating")
p.rightCS.Unlock()
p.leftCS.Unlock()
}
}
//main
CSticks := make([]*ChopS, 5)
for i := 0; i < 5; i++ {
CSticks[i] = new(ChopS)
}
philos := make([]*Philo, 5)
for i := 0; i < 5; i++ {
philos[i] = &Philo{Csticks[i], Csticks[(i+1)%5]}
}
CSticks := make([]*ChopS, 5)
for i := 0; i < 5; i++ {
CSticks[i] = new(ChopS)
}
philos := make([]*Philo, 5)
for i := 0; i < 5; i++ {
philos[i] = &Philo{Csticks[i], Csticks[(i+1)%5]}
}
// cena main
for i := 0; i < 5; i++ {
go philos[i].eat()
}
//comida
p.leftCS.Lock()
p.rightCS.Lock()
fmt.Println("eating")
p.rightCS.Unlock()
p.leftCS.Unlock()
更多关于Golang中如何解决哲学家就餐问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
更多关于Golang中如何解决哲学家就餐问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是解决哲学家就餐问题的Go语言实现,满足所有要求:
package main
import (
"fmt"
"sync"
"time"
)
type ChopS struct{ sync.Mutex }
type Philo struct {
leftCS, rightCS *ChopS
id int
eatCount int
host chan bool
}
func (p *Philo) eat(wg *sync.WaitGroup) {
defer wg.Done()
for p.eatCount < 3 {
// 请求主机许可
p.host <- true
p.leftCS.Lock()
p.rightCS.Lock()
fmt.Printf("开始用餐 %d\n", p.id)
time.Sleep(100 * time.Millisecond) // 模拟用餐时间
fmt.Printf("结束用餐 %d\n", p.id)
p.rightCS.Unlock()
p.leftCS.Unlock()
// 释放主机许可
<-p.host
p.eatCount++
}
}
func hostManager(host chan bool, maxEaters int) {
for i := 0; i < maxEaters; i++ {
host <- true
}
}
func main() {
// 创建5根筷子
CSticks := make([]*ChopS, 5)
for i := 0; i < 5; i++ {
CSticks[i] = new(ChopS)
}
// 创建主机通道,限制最多2位哲学家同时用餐
host := make(chan bool, 2)
// 创建5位哲学家
philos := make([]*Philo, 5)
for i := 0; i < 5; i++ {
philos[i] = &Philo{
leftCS: CSticks[i],
rightCS: CSticks[(i+1)%5],
id: i + 1,
host: host,
}
}
var wg sync.WaitGroup
// 启动主机管理器
go hostManager(host, 2)
// 启动哲学家协程
for i := 0; i < 5; i++ {
wg.Add(1)
go philos[i].eat(&wg)
}
// 等待所有哲学家完成3次用餐
wg.Wait()
}
这个实现的关键特性:
- 主机控制:使用带缓冲的通道
host限制最多2位哲学家同时用餐 - 死锁避免:通过主机限制避免了传统的死锁问题
- 用餐计数:每位哲学家只吃3次
- 正确的锁顺序:使用通道机制避免了锁顺序问题
- 完整的输出:按要求打印开始用餐和结束用餐信息
运行示例输出:
开始用餐 1
结束用餐 1
开始用餐 2
结束用餐 2
开始用餐 3
结束用餐 3
...
这个实现确保了所有要求:5位哲学家、共享筷子、每人吃3次、最多2人同时用餐,并且避免了死锁。

