étkező filozófusok problémája

Kiejtés

  • IPA: [ ˈeːtkɛzøː ˈfilozoːfuʃok ˈprobleːmaːjɒ]

Főnév

étkező filozófusok problémája

  1. (matematika, algoritmusok)

Étköző filozófusok problémája

Definíció

Az étkező filozófusok problémája egy klasszikus szinkronizációs probléma, amelyet Edsger Dijkstra vezetett be a párhuzamos programozás kihívásainak modellezésére. A probléma öt filozófust képzel el, akik körben ülnek egy asztal körül. Minden filozófus váltakozva gondolkodik és eszik, de az evéshez két szomszédos villára van szüksége. A probléma célja annak biztosítása, hogy a filozófusok ne kerüljenek holtpontba vagy éhezzenek.



Feltételek

  1. Minden filozófus:
    • Gondolkodik, majd eszik.
    • Az evéshez két villára van szüksége: egy a jobb, egy a bal oldali filozófusétól.
  2. Villák (két szomszédos filozófus között) megosztott erőforrások.
  3. Szinkronizáció szükséges a villák megosztásához.

Problémák:

  1. Holtpont: Ha minden filozófus egyszerre próbál villát szerezni, senki nem fog tudni enni.
  2. Éhezés: Ha egy filozófus sosem kap mindkét villát, sosem tud enni.



Megoldás

A megoldáshoz szinkronizációs mechanizmusokat, például mutexeket és semaphore-okat használhatunk. Pythonban a threading modul lehetőséget biztosít a párhuzamos szálak szinkronizálására.



Python Implementáció

Az alábbi megoldás a filozófusok viselkedését modellezi egy párhuzamos szálakra bontott programmal. Minden filozófus saját szálként fut, és a villák (mint megosztott erőforrások) threading.Lock segítségével kerülnek szinkronizálásra.

import threading
import time
import random

class Philosopher(threading.Thread):
    def __init__(self, name, left_fork, right_fork):
        super().__init__()
        self.name = name
        self.left_fork = left_fork
        self.right_fork = right_fork

    def think(self):
        print(f"{self.name} gondolkodik...")
        time.sleep(random.uniform(1, 3))

    def eat(self):
        print(f"{self.name} eszik...")
        time.sleep(random.uniform(1, 3))
        print(f"{self.name} befejezte az evést.")

    def run(self):
        while True:
            self.think()
            print(f"{self.name} megpróbálja felvenni a bal villát.")
            with self.left_fork:
                print(f"{self.name} felvette a bal villát. Most megpróbálja felvenni a jobb villát.")
                with self.right_fork:
                    print(f"{self.name} mindkét villát felvette. Most eszik.")
                    self.eat()

def main():
    # Villák (megosztott erőforrások)
    forks = [threading.Lock() for _ in range(5)]

    # Filozófusok
    philosophers = [
        Philosopher(f"Filozófus {i+1}", forks[i], forks[(i+1) % 5])
        for i in range(5)
    ]

    # Filozófusok indítása
    for philosopher in philosophers:
        philosopher.start()

    # Futtatás végtelenségig
    for philosopher in philosophers:
        philosopher.join()

if __name__ == "__main__":
    main()

Magyarázat

  1. Villák megosztása:
    • Az egyes filozófusok a szomszédos villáikat próbálják megszerezni.
    • A villák threading.Lock segítségével kerülnek zárolásra, így egyszerre csak egy filozófus használhatja őket.
  2. Holtpont elkerülése:
    • A villák megszerzését szabályozza a with utasítás, amely biztosítja, hogy egy filozófus mindkét villát egyszerre szerezze meg.
  3. Párhuzamosság:
    • Minden filozófus szála függetlenül fut, a szinkronizációt a villák zárolása biztosítja.
  4. Gondolkodási és evési szimuláció:
    • A time.sleep szimulálja a gondolkodás és evés időtartamát.



Példa Kimenet

Filozófus 1 gondolkodik...
Filozófus 2 gondolkodik...
Filozófus 3 gondolkodik...
Filozófus 4 gondolkodik...
Filozófus 5 gondolkodik...
Filozófus 1 megpróbálja felvenni a bal villát.
Filozófus 1 felvette a bal villát. Most megpróbálja felvenni a jobb villát.
Filozófus 1 mindkét villát felvette. Most eszik.
Filozófus 3 megpróbálja felvenni a bal villát.
Filozófus 3 felvette a bal villát. Most megpróbálja felvenni a jobb villát.
Filozófus 3 mindkét villát felvette. Most eszik.
...

További fejlesztések

  1. Holtpont további elkerülése:
    • A villák megszerzését szabályozhatjuk egy központi semaphore használatával, amely biztosítja, hogy legfeljebb (n-1) filozófus próbáljon egyszerre villát szerezni.
  2. Éhezés kezelése:
    • Időbélyegeket használhatunk a filozófusok viselkedésének nyomon követésére, hogy biztosítsuk, hogy senki ne várjon túl sokáig a villákra.



Összegzés

Az étkező filozófusok problémája remek példa a párhuzamos programozásban felmerülő szinkronizációs problémákra. A Python threading modulja egyszerűen lehetővé teszi a szálak közötti erőforrás-megosztás kezelését. Ez a megoldás alapvetően biztonságos és hatékony módot biztosít a probléma modellezésére.

Fordítások