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 Bridge 🚀🎆

你遇到的情况和之前你同学遇到的问题完全一样:链接

随时关注他/她的发现进展。

更多关于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()
}

这个实现的关键特性:

  1. 主机控制:使用带缓冲的通道host限制最多2位哲学家同时用餐
  2. 死锁避免:通过主机限制避免了传统的死锁问题
  3. 用餐计数:每位哲学家只吃3次
  4. 正确的锁顺序:使用通道机制避免了锁顺序问题
  5. 完整的输出:按要求打印开始用餐和结束用餐信息

运行示例输出:

开始用餐 1
结束用餐 1
开始用餐 2
结束用餐 2
开始用餐 3
结束用餐 3
...

这个实现确保了所有要求:5位哲学家、共享筷子、每人吃3次、最多2人同时用餐,并且避免了死锁。

回到顶部