یئمک یئین فیلسوف‌لارین مساله‌سی

بیلگی‌سایار بیلیمینده، یئمک یئین دوشونورلرین (فیلسوف‌لارین) مساله‌سی (اینگیلیسجه: dining philosophers problem)، سینکرونیزاسیون سورونلارینی و اونلاری حل ائتمه تکنیک‌لرینی گؤسترمک اوچون ائش زامانلی الگوریتم‌لرین تاساریمیندا تئز-تئز قوللانیلان بیر اؤرنکدیر.

يئمک یئین فیلسوف‌لارین مساله‌سی

ایلک اولاراق ۱۹۶۵-جی ایلده ادسخر دیکسترا طرفیندن بیلگی‌سایارلاری تیپ سوروجوسونه ال تاپماق اوچون یاریشامالاری آچیسیندان گؤسترن بیر اؤیرنجی سیناو تمرینی کیمی فرموله ائدیلمیش. قیسا بیر زامان سونرا تونی هور مساله‌یه بوگونکو شکلینی وئردی.

مسئله‌نین آچیقلاماسی دَییشدیر

بئش فیلسوف بیر ماسادا بیر‌لیکده یئمک یئییرلر. هر بیر فیلوسوفون ماسادا اؤزونه عایید بیر بوشقابی وار. هر بوشقاب آرا‌سیندا بیر چنگال وار. وئریلن یئمک ایکی چنگاللا یئییله بیلن بیر اسپاگئتتی نوعودور. هر بیر فیلوسوف یالنیز دؤنوشوملو اولاراق (نوبه ایله) دوشونه بیلر و یا یئمک یئیه بیلر. اوسته‌لیک، بیر فیلسوف اسپاگئتتینی یالنیز هم سول، هم‌ده ساغ چنگالی اولاندا یئیه بیلر. بئله‌‌لیکله، ایکی چنگال ایکی ساغ و سول قونشونون یئمک یئیرکن دئییل، دوشوندوکلرینده قوللانیلا بیلر. بیر فیلسوف یئمه‌یینی بیتیردیکدن سونرا هر ایکی چنگالی یئره قویور. سورون، هئچ بیر فیلسوفون آجلیقدان اؤلمه‌یه‌جه‌یینی ساغلایان بیر رئژیمین (ائش زامانلی الگوریتمی) نئجه تاسارلاناجاغیدیر؛ یعنی هئچ بیر فیلسوفون باشقا‌لاری‌نین نه واخت یئمک و یا دوشونمک ایسته‌یه‌جه‌یینی بیلمه‌یه‌جه‌یینی توتارساق، هر بیری سونسوزا قدر یئمک و دوشونمک آرا‌سیندا کئچید ائتمه‌یه داوام ائده بیلر (اکسیک بیلگی سورونو).

سورون‌لار دَییشدیر

سورون، هئچ بیر ایله‌رله‌مه‌نین مومکون اولمادیغی بیر سیستئم دورومو اولان "چیخیلماز دوروم" چتین‌لیک‌لر‌ینی گؤسترمک اوچون تاسارلانمیشدیر. بو سورونون هئچ بیر آچیق حللی‌نین آچیق اولمادیغینی گؤرمک اوچون هر بیر فیلسوفون آشاغیداکی کیمی حرکت ائتمه‌سینین تاپشیریلدیغی بیر تکلیفی نظردن کئچیرین:

  • سول چنگال موجود اولمادیغی زامانا قدر دوشون، اولدوغوندا گؤتور
  • ساغ چنگال موجود اولمادیغی زامانا قدر دوشون، اولدوغوندا گؤتور
  • هر ایکی چنگال الینده اولسا بللی بیر زامانا قدر یئمک یئه
  • سول چنگالی یئره قوی؛
  • ساغ چنگالی یئره قوی؛
  • باشلانيشدان تکرار ائت.

بونونلا بیرلیکده، هر فیلسوف بللی اولمایان بیر زامانا قدر دوشونمه‌یه دوام ائده‌جک و آجلیقدان اؤله‌نه قدر، سول چنگالی الینده ساخلایاراق، بوشقابین ساغ طرفینه باخاراق و ساغ چنگال اولمادیغی اوچون یئمک یئیه‌مه‌یه‌جک شکیلده دوشونه بیلیر.

حل یول‌لاری دَییشدیر

دیکسترا حل یولو دَییشدیر

آشاغیدا گولنگ یازیلمالا دیلی ایله یازیلان کود، موتکس (mutex)، گوروتین (goroutine) و کانال (channel) قوللاناراق دیکسترا حل یولونو گؤسته‌ریر.

  • هر بیر فیلسوف بیر گوروتین ایله تمثیل اولونور.
  • eat مئتودو، فیلسوفون هر ایکی چنگالی دا گؤتوروب یئمک یئمه‌یی تمثیل ائدیر.
  • think مئتودو فیلسوفون دوشونمه‌سینی تمثیل ائدیر.
package main

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

type Philosopher struct {
    id                   int
    leftFork, rightFork *sync.Mutex
}

func (p Philosopher) eat() {
    p.leftFork.Lock()
    p.rightFork.Lock()

    fmt.Printf("Philosopher %d is eating\n", p.id)
    time.Sleep(2 * time.Second) // Simulate eating

    fmt.Printf("Philosopher %d finished eating\n", p.id)

    p.leftFork.Unlock()
    p.rightFork.Unlock()
}

func (p Philosopher) think() {
    fmt.Printf("Philosopher %d is thinking\n", p.id)
    time.Sleep(2 * time.Second) // Simulate thinking
}

func philosopher(id int, leftFork, rightFork *sync.Mutex, wg *sync.WaitGroup) {
    defer wg.Done()
    p := Philosopher{id, leftFork, rightFork}
    for i := 0; i < 3; i++ { // Each philosopher will eat 3 times
        p.think()
        p.eat()
    }
}

func main() {
    numPhilosophers := 5
    forks := make([]*sync.Mutex, numPhilosophers)
    for i := 0; i < numPhilosophers; i++ {
        forks[i] = &sync.Mutex{}
    }

    var wg sync.WaitGroup

    // Start philosophers
    for i := 0; i < numPhilosophers; i++ {
        wg.Add(1)
        go philosopher(i, forks[i], forks[(i+1)%numPhilosophers], &wg)
    }

    // Wait for all philosophers to finish
    wg.Wait()
}

قایناق سلسه مراتبی حل یولو دَییشدیر

package main

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

type Philosopher struct {
	id              int
	leftFork, rightFork *sync.Mutex
}

func (p Philosopher) eat() {
	p.leftFork.Lock()
	p.rightFork.Lock()

	fmt.Printf("Philosopher %d is eating\n", p.id)
	time.Sleep(2 * time.Second) // Simulate eating

	fmt.Printf("Philosopher %d finished eating\n", p.id)

	p.leftFork.Unlock()
	p.rightFork.Unlock()
}

func (p Philosopher) think() {
	fmt.Printf("Philosopher %d is thinking\n", p.id)
	time.Sleep(2 * time.Second) // Simulate thinking
}

func philosopher(id int, leftFork, rightFork *sync.Mutex, wg *sync.WaitGroup) {
	defer wg.Done()
	p := Philosopher{id, leftFork, rightFork}
	for i := 0; i < 3; i++ { // Each philosopher will eat 3 times
		p.think()
		p.eat()
	}
}

func main() {
	numPhilosophers := 5
	forks := make([]*sync.Mutex, numPhilosophers)
	for i := 0; i < numPhilosophers; i++ {
		forks[i] = &sync.Mutex{}
	}

	var wg sync.WaitGroup

	// Start philosophers
	for i := 0; i < numPhilosophers; i++ {
		wg.Add(1)
		// Assign forks in increasing order of indices
		leftFork := forks[i]
		rightFork := forks[(i+1)%numPhilosophers]
		if i == numPhilosophers-1 {
			// To avoid deadlock, swap forks for the last philosopher
			leftFork, rightFork = rightFork, leftFork
		}
		go philosopher(i, leftFork, rightFork, &wg)
	}

	// Wait for all philosophers to finish
	wg.Wait()
}

قایناقلار دَییشدیر

اینگیلیسجه ویکی‌پدیاسی‌نین ایشلدنلری طرفیندن یارانمیش «Dining philosophers problem»، مقاله‌سیندن گؤتورولوبدور. (3 آپریل ۲۰۲۴ تاریخینده یوْخلانیلیبدیر).