Hlavní navigace

Programování pod Linuxem pro všechny (19)

Jakub Matys

Dnes se podíváme na třetí prostředek, který je možné použít k synchronizaci vláken - podmíněnné proměnné. Jedná se o první část, která nastíní problém.

Třetím prostředkem k synchronizaci činnosti vláken v Linuxu je podmíněná proměnná. Pomocí podmíněných proměnných můžete určovat komplexnější podmínky, za kterých budou realizována jednotlivá vlákna.

Předpokládejme, že jste napsali funkci vlákna, která realizuje nekonečný cyklus a při každém průchodu cyklem provede nějakou práci. Takový cyklus ovšem musí být kontrolován nějakým příznakem (stavovou proměnnou). Pokud je příznak nastaven, cyklus se bude provádět, jinak bude ve vyčkávacím stavu.

Příklad ukazuje implementaci takového cyklu. V průběhu každého průchodu cyklem kontroluje funkce vlákna, zda je příznak nastaven. Protože je příznak zpřístupňován více vlákny, je chráněn mutexem. Program však není efektní. Funkce vlákna spotřebuje velké množství času procesoru, kdykoliv příznak není nastaven, protože bude stále dokola ověřovat jeho hodnotu. Efektivnější by bylo uvést vlákno do nečinného stavu, není-li příznak nastaven, a až za jistých okolností by se měl příznak nastavit.

#inclue <pthread.h>

int thread_flag;
pthread_mutex_t thread_flag_mutex;

void initialize_flag()
{
    pthread_mutex_init(&thread_flag_mutex, NULL);
    thread_flag = 0;
}

/* Vola opakovane funkci do_work, pokud je
   nastaven priznak */

void *thread_function(void *thread_arg)
{
    while(1) {
        int flag_is_set;

        /* Priznak je chranen zamcenim mutexu */
        pthread_mutex_lock(&thread_flag_mutex);
        flag_is_set = thread_flag;
        pthread_mutex_unlock(&thread_flag_mutex);

        if (flag_is_set)
            do_work();
    }
    return(NULL);
}

/* Nastavi hodnotu priznaku */

void set_thread_flag(int flag_value)
{
    /* Priznak je chranen zamcenim mutexu */
    pthread_meutex_lock(&thread_flag_mutex);
    thread_flag = flag_value;
    pthread_mutex_unlock(&thread_flag_mutex);
}

Podmíněná proměnná umožňuje implementovat podmínku, za které bude vlákno vykonávat svoji činnost, a nopak, nebude-li podmínka splněna, bude vlákno zablokováno. Pokud bude každé vlákno používající podmíněnou proměnnou měnit smysl podmínky korektně, operační systém Linux garantuje, že vlákna zablokovaná při splnění podmínky budou odblokována, jakmile bude podmínka změněna.

Podobně jako v případě semaforu, vlákno může čekat na podmíněnou proměnnou. Jestliže vlákno A čeká na podmíněnou proměnnou, je zablokováno, dokud jiné vlákno B podmínku nezmění. Jestliže vlákno B změní podmínku předtím, než vlákno A na změnu podmínky začne čekat, signál o změně podmínky je ztracen a vlákno A je zablokováno až do okamžiku, kdy nějaké jiné vlákno podmínku změní.

Nyní si popišme, jak náš problém s podmíněnou proměnou řešit efektivněji.

  • Cyklus ve funkci thread_function ověří příznak. Není-li příznak nastaven, vlákno bude čekat na změnu podmíněné proměnné.
  • Funkce set_thread_flag signalizuje změnu podmíněné proměnné po změně příznaku. Pokud je funkce thread_function zablokována podmíněnou proměnnou, bude odblokována a bude testovat podmínku znovu.

V uvedeném postupu je však jeden problém. Nastává stav souběhu mezi ověřováním hodnoty příznaku a čekáním na podmíněnou proměnnou. Předpokládejme, že funkce thread_function ověřila příznak a že jej shledala nenastaveným. Dále předpokládejme, že v tomto okamžiku operační systém Linux pozastavil vlákno a spustil hlavní vlákno, a také předpokládejme, že nešťastnou náhodou je hlavní vlákno (vlákno funkce main()) ve funkci set_thread_flag. Tato funkce nastaví příznak a signalizuje změnu podmíněné proměnné. Protože však žádné vlákno nečeká v tomto okamžiku (funkce thread_function byla pozastavena, aby mohla čekat na změnu podmínky) na podmíněnnou proměnnou, signalizace změny podmíněné proměnné se ztratí. Nyní, když operační systém Linux spustí jiné vlákno, začne toto vlákno čekat na podmíněnou proměnnou a může se zablokovat navždy.

Problém lze řešit uzamčením příznaku a podmíněnné proměnné spolu s mutexem. Praktickou ukázku řešení si však necháme na příště – máte se tedy na co těšit.

Našli jste v článku chybu?

4. 6. 2004 22:28

happz (neregistrovaný)

Placete na spatnem hrobe: prvni komentar nespila neefektivite ukazaneho kodu - o kterem navic sam autor rika, ze neni zrovna nejlepsi, a dodava, ze reseni prijde v pristim dile - ale zamene sluvka efektni za vhodnejsi efektivni...

Tyhle podminene promenne jsou "na to" zrejme take jak delane...



4. 6. 2004 16:26

Jerry III (neregistrovaný)

Tak nejak, zlaty event nebo semaphore nebo completion ports objekty na Win, ktery sou na tohle jak delany, clovek tam nemusi mit pustenej loop, kterej pokud bezi na stejny priorite jako zbytek uplne zbytecne vytizi CPU.

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

DigiZone.cz: Flix TV startuje i na Slovensku

Flix TV startuje i na Slovensku

DigiZone.cz: „Black Friday 2016“: závěrečné zhodnocení

„Black Friday 2016“: závěrečné zhodnocení

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Vitalia.cz: Co pomáhá dítěti při zácpě?

Co pomáhá dítěti při zácpě?

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum