哲学家就餐问题 条件变量

之前一直很少用到条件变量,最近看了看,顺便尝试写了写哲学家就餐问题。

问题描述

如图,五个哲学家围着圆桌吃意面,每位哲学家或者拿起左右手边的叉进食,或者放回两边的叉思考。经典的死锁问题。


哲学家就餐问题 条件变量_第1张图片
An_illustration_of_the_dining_philosophers_problem.png

Code

package main

import (
    "fmt"
    "sync"
    "time"
)

type philosopher struct {
    id     int
    eating bool
    left   *philosopher
    right  *philosopher
    table  *sync.Mutex
    cond   *sync.Cond
}

func (p *philosopher) run() {
    for {
        p.think()
        p.eat()
    }
}

func (p *philosopher) think() {
    p.table.Lock()
    p.eating = false
    p.left.cond.Signal()
    p.right.cond.Signal()
    p.table.Unlock()

    fmt.Printf("==philosopher %d Think\n", p.id)
    time.Sleep(time.Second) // 根据需要改成sleep随机时间
}

func (p *philosopher) eat() {
    p.table.Lock()
    for p.left.eating || p.right.eating {
        p.cond.Wait()
    }
    p.eating = true
    p.table.Unlock()

    fmt.Printf("  philosopher %d Eat\n", p.id)
    time.Sleep(time.Second) // 根据需要改成sleep随机时间
}

func main() {
    var table sync.Mutex
    var pher [5]philosopher

    for i := 0; i < 5; i++ {
        pher[i].id = i + 1
        pher[i].left, pher[i].right = &pher[(i+4)%5], &pher[(i+1)%5]
        pher[i].table = &table
        pher[i].cond = sync.NewCond(&table)
    }
    for i := 0; i < 5; i++ {
        go pher[i].run()
    }

    // 无限等待
    var wg sync.WaitGroup
    wg.Add(1)
    wg.Wait()
}

作者原创,转载请注明出处

你可能感兴趣的:(哲学家就餐问题 条件变量)