cigarette smokers problem
Főnév
cigarette smokers problem (tsz. cigarette smokers problems)
- (informatika) A Cigarette Smokers Problem egy klasszikus szinkronizációs probléma, amelyet Su Yen és P. Brinch Hansen vezetett be az 1970-es években, és amit Tony Hoare is elemzett. A probléma célja: megérteni és demonstrálni a versenyhelyzetek, éhezés (starvation), és szinkronizáció komplexitását a konkurens programozásban.
🧠 A probléma lényege
Van három dohányos és egy ügynök (agent). Minden dohányosnak van egy adott végtelen készlete egy adott hozzávalóból, és csak akkor tud cigit sodorni és elszívni, ha a másik két összetevőt megkapja az ügynöktől.
A három hozzávaló:
- Dohány
- Papír
- Gyufa
A szereplők:
- Dohányos 1: csak dohánya van
- Dohányos 2: csak papírja van
- Dohányos 3: csak gyufája van
Az ügynök viselkedése:
- Véletlenszerűen két összetevőt tesz ki az asztalra.
- A dohányosok figyelik az asztalt, és az, aki a hiányzó harmadik összetevővel rendelkezik, az reagál, elkészíti a cigarettát, elszívja, majd jelzi, hogy kész van.
🧩 A szinkronizációs kihívás
- Csak az a dohányos reagálhat, aki a megfelelő hozzávalóval rendelkezik.
- A többieknek várakozniuk kell.
- Az ügynöknek várnia kell, amíg az asztal üres nem lesz (a dohányos befejezte).
- Éhezés (starvation) elkerülése: minden dohányos előbb-utóbb dohányozhasson.
- Versenyhelyzetek megelőzése: egyszerre ne több dohányos reagáljon.
🔧 Klasszikus megoldás (semaphore-ral, pseudokód)
Változók:
mutex: kizárásraagent: szignál az ügynöknek, hogy új kör indulhatsmoker_tobacco,smoker_paper,smoker_match: külön semafor a dohányosoknaktobacco,paper,match: boolean flag-ek vagy semaforok
Ügynök (agent) pseudokód:
while (true) {
wait(agent); // csak akkor, ha az előző ciklus befejeződött
pick two items at random;
signal(semaphore for the smoker with the missing item);
}
Dohányos:
smoker_with_tobacco:
while (true) {
wait(smoker_tobacco); // jelet kap, ha papír + gyufa van az asztalon
make cigarette;
signal(agent); // ügynök mehet újra
smoke;
}
Ez a logika minden dohányosnál hasonló, csak más hozzávalóra “vár”.
🧠 Alternatív megoldás: közös asztal + monitor
Használható monitor, amely kezeli az összetevőket és kizárja az egyidejű hozzáférést:
monitor Table {
bool tobacco, paper, match;
condition can_smoke[3]; // minden dohányos külön várakozhat
procedure put(item1, item2) {
// frissítjük az asztal állapotát
set items true;
signal appropriate smoker;
}
procedure take(int smoker_id) {
// dohányos elveszi, amire szüksége van
reset table;
signal(agent);
}
}
🎯 Kulcsproblémák
1. Fairness (méltányosság)
- Nem lehet, hogy mindig ugyanaz a dohányos jut cigarettához → meg kell akadályozni az éhezést (starvation).
2. Mutual exclusion (kölcsönös kizárás)
- Egyszerre csak egy dohányos dolgozhat az asztalon.
3. Deadlock avoidance (holtpont elkerülése)
- Ne várakozzanak egymásra örökké.
4. Szinkronizáció helyessége
- Az ügynöknek várnia kell, amíg az asztal üres.
- A dohányosnak csak akkor szabad reagálnia, ha az ő kombinációja van kint.
🖥️ C++ megvalósítás vázlat (std::thread + semaphore mintával)
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv_agent, cv_smoker[3];
bool table_ready = false;
int available_items = 0; // 0: dohány, 1: papír, 2: gyufa (kettőt tárolunk)
void agent() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv_agent.wait(lock, []{ return !table_ready; });
// random két elem
int i1 = rand() % 3;
int i2 = (i1 + 1 + rand() % 2) % 3;
table_ready = true;
int smoker_id = 3 - i1 - i2; // hiányzó összetevő = dohányos id
cv_smoker[smoker_id].notify_one();
}
}
void smoker(int id) {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv_smoker[id].wait(lock);
// cigaretta készítése
table_ready = false;
std::cout << "Smoker " << id << " is smoking\n";
cv_agent.notify_one();
lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
📚 Fontos tanulságok
- Egyértelmű példája a több szereplős szinkronizációs problémáknak
- Nem-triviális vezérlés: a dohányosnak ki kell derítenie, mikor léphet
- Kiváló oktatási példa a következőkre:
- szemináriumok/semaforok használata
- monitor szinkronizáció
- holtpont és éhezés felismerése
🧠 Kapcsolódó problémák
- Dining Philosophers Problem – hasonló, de filozófusok és evőpálcikák vannak benne
- Readers-Writers Problem – olvasók és írók megosztott adat felett
- Producer–Consumer Problem – pufferek és adatáramlás
🔚 Összegzés
A Cigarette Smokers Problem nemcsak szórakoztató, hanem mélyen oktató példa arra, hogyan lehet helyesen vezérelni több folyamat viselkedését, miközben konfliktusokat, éhezést és versenyhelyzeteket kerülünk el. A probléma különösen fontos a konkurens programozás oktatásában, hiszen világosan rámutat arra, hogy a szinkronizáció nem csupán zárolás, hanem gondos logikai tervezés kérdése.
- cigarette smokers problem - Szótár.net (en-hu)
- cigarette smokers problem - Sztaki (en-hu)
- cigarette smokers problem - Merriam–Webster
- cigarette smokers problem - Cambridge
- cigarette smokers problem - WordNet
- cigarette smokers problem - Яндекс (en-ru)
- cigarette smokers problem - Google (en-hu)
- cigarette smokers problem - Wikidata
- cigarette smokers problem - Wikipédia (angol)