3. cvičení - Semafory

Užitečné odkazy

Semaphore Objects

Semafor je nejstarší synchronizační primitivum vytvořené informatikem Edsger W. Dijkstrou, který používal názvy P() a V() místo acqiure() a release().

Semafor interně obsahuje čítač, kdy každé volání acquire() dekrementuje tento vnitřní čítač a volání release() tento čítač inkrementuje. Hodnota tohot čítače nikdy neklesne do záporných hodnot, v případě, že je jeho hodnota rovna 0 a zavoláme acquire() tak volání blokuje dané vlákno do doby než jiné vlákno zavolá release().

    
    import threading

    # Vytvoření semaforu
    mutex = threading.Semaphore(1)

    def function_with_critical_section():
        global mutex

        # Nekritická sekce
        mutex.acquire()
        # Kritická sekce
        mutex.release()

    # Vytvoření vláken

    t1 = threading.Thread(target=function_with_critical_section)
    t2 = threading.Thread(target=function_with_critical_section)

    t1.start()
    t2.start()

    t1.join()
    t2.join()


    # V kritické sekci múže dojít k chybě jako neexistující soubor,
    # program nemá právo číst/zapisovat do souboru, apod.
    # Musíme tedy zajistit, že i při chybě dojde k uvolnění mutexu.

    mutex.acquire()
    try:
        # Kód, kde může dojít k vyjímce
    finally:
        # Tento blok se vykoná pokaždé bez ohledu na to jestli chyba nastala či ne.
        mutex.release()

    # Výše uvedenou kontrukci můžeme zapsat pomocí with
    with mutex:
        # Kód, kde může dojít k vyjímce
    

Úkoly

Upravte úkol 1 ze 2. cvičení tak, aby přístup ke sdílené proměnné byl synchronizován.

Napište program, kde budou 3 procesy. První bude producent a bude generovat dvojice náhodných čísel. Druhý proces bude zjíšťovat jestli jsou tato dvě čísla soudělná. Pokud ne, tak bude třetímu procesu poslána 1 jinak 0. Třetí proces bude počítat počet jedniček a počet všech čísel která mu pošle druhý proces.

(Bodovaný) Upravte druhý úkol tak, aby program skončil pokud třetí proces obdrží N jedniček.