Hlavní navigace

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

Jakub Matys 9. 4. 2004

Dnes nás čeká další zajímavé téma: vlákna. Pokusím se vám vysvětlit, co to vlákna jsou a jak vytvořit nové vlákno.

Vlákna

Vlákna, podobně jako procesy, umožňují aplikaci realizovat více činností najednou. Podobně jako procesy se vlákna jeví jako běžící současně. Jádro systému plánuje jejich činnost asynchronně – vlákna přerušuje, aby přidělilo čas procesoru jiným vláknům.

Koncepčně je vlákno řešeno tak, že běží uvnitř procesu. Vlákno vlastně představuje realizaci procesu na „jemnější“ úrovni. Když spustíte nějaký program, Linux vytvoří nový proces a v tomto procesu vytvoří vlákno. Toto vlákno může vytvářet další vlákna – všechna tato vlákna realizují tentýž program a běží v tomtéž procesu. Přitom každé vlákno může realizovat jinou úlohu programu, a to v kterémkoliv daném čase.

Všechna vlákna v procesu sdílí tutéž paměť, tytéž deskriptory a ostatní systémové zdroje. Pokud nějaké vlákno změní hodnotu určité proměné, bude tato proměnná modifikována pro všechna vlákna v procesu. To samé platí pro deskriptory souborů, pokud jedno vlákno uzavře deskriptor souboru, ostatní vlákna nemohou dále provádět operace s tímto souborem. Protože všechna vlákna běží v rámci jediného procesu, platí, že pokud jedno vlákno zavolá funkci exec, všechna ostatní vlákna se ukončí, protože proces začne realizovat jiný kód (ale jiný proces může samozřejmě vytvářet nová vlákna).

Operační systém Linux implentuje vlákna odpovídající standardu POSIX. Všechny funkce a konstanty pro práci s vlákny jsou definovány v hlavičkovém souboru pthread.h. Tyto funkce nejsou součástí standardní knihovy C, proto musíte při sestavování programu zadat gcc volbu -lpthread.

Vytváření vláken

Každé vlákno je v procesu určeno svým identifikačním číslem. Pokud budete používat proměnnou pro ukládání tohoto čísla, deklarujte ji pomocí typu pthread_t.

V okamžiku vytvoření realizuje každé vlákno speciální funkci vlákna (thread function). Tato funkce je pouze obyčejná funkce obsahující kód, který má vlákno realizovat jako první. Když se funkce vrátí, vlákno bylo vytvořeno. Funkce vlákna má jediný parametr typu void * a jejím návratovým typem je opět void *. Parametr funkce se nazývá argument vlákna a systém předává tento parametr, aniž by jej ověřoval. Parametr lze využít k předávání dat do vlákna nebo k přenosu dat z vlákna do volajícího kódu.

Nové vlákno vytvoříte pomocí funkce pthread_create(). Funkci se předávají tyto argumenty:

  1. Ukazatel na proměnnou typu pthread_t, do které se uloží identifikační číslo nově vytvořeného vlákna.
  2. Ukazatel na objekt atribut vlákna (thread attribute). Tento objekt obsahuje detailní informace o tom, jak má vlákno komunikovat se zbývajícími komponentami programu. Pokud prostřednictvím tohoto parametru předáte NULL, budou nastaveny implicitní atributy. Podrobnosti uvedu v některém z příštích dílů.
  3. Ukazatel na funkci vlákna. Jedná se o obyčejný ukazatel na funkci typu:

    void *(*) (void *)
  4. Argument vlákna pro přenos dat typu void *. Pomocí tohoto argumentu můžete předávat funkci jakákoliv data.

Volání funkce pthread_create() se vrací okamžitě a původní vlákno pokračuje další instrukcí za tímto voláním. Mezitím nové vlákno začíná realizovat kód, který je obsažen ve funkci vlákna. Systém plánuje vlákna asynchronně, a proto se nemůžete spoléhat na relativní pořadí, ve kterém jsou instrukce prováděny ve dvou či více vláknech.

Program v příkladu vytvoří nové vlákno, které nepřetržitě tiskne do stderr písmena x. Po zavolání funkce pthread_create() tiskne hlavní vlákno opakovaně písmena o do stderr.

#include <pthread.h>
#include <stdio.h>

/* Funkce vlakna - tiskne pismena x do stderr.
   Parametr neni pouzivan. Funkce se nevraci. */

void *print_x(void *unused)
{
  while(1)
    fputc('x', stderr);
  return(NULL);
}

int main()
{
  pthread_t thread_id;
  /* Vytvori nove vlakno. Nove vlakno bude
     vykonavat funkci print_x(). */
  pthread_create(&thread_id, NULL, &print_x, NULL);
  /* Tiskne pismena o do stderr. */
  while(1)
    fputc('o', stderr);
  return(0);
}

Pokud program přeložíte (nesmíte zapomenout na volbu -lpthread) a spustíte, začnou se na obrazovce střídavě zobrazovat skupiny písmen x a o, a to zcela nepravidelně. Je tomu tak proto, že Linux plánuje přidělování času vláknům asynchronně.

Za normálních okolností se vlánko ukončuje jedním ze dvou způsobů. Prvním je návrat z funkce vlákna, návratová hodnota funkce se považuje za návratovou hodnotu vlákna. Ten byl demonstrován v příkladu (i když nebude nikdy použit). Druhý způsob, jak vlákno ukončit, představuje volání funkce pthread_exit(). Tato funkce může být volána z funkce vlákna nebo z některé jiné funkce (přímo nebo nepřímo). Jediným argumentem funkce je návratový kód vlákna.

Myslím, že pro dnešek toho bylo až až. V příštím dílu se podíváme na předávání dat do vlákna, spojování vláken a povíme si něco o návratových kódech vláken.

Našli jste v článku chybu?

7. 8. 2007 11:38

Petr1982 (neregistrovaný)
Ahoj,
portuju jednu aplikaci z Netbeans v Linuxu na Netbeans pod Win. a m8m probl0my s pthreadama. Něřešili jste někdo tento problém?

Díky Petr


25. 5. 2004 19:45

Taif (neregistrovaný)

Autor bohuzel jen opisuje knihu Pokrocile programovani v operacnim systemu Linux :(. Mimoto v textu je plno chyb ... napr vlakna ovlivnuji jen globalni promenne (jak by hnula se stackem me nenapada) ...

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

Přehledná titulka, průvodci, responzivita

DigiZone.cz: Další dva kanály nabídnou HbbTV

Další dva kanály nabídnou HbbTV

Vitalia.cz: I církev dnes vyrábí potraviny

I církev dnes vyrábí potraviny

Vitalia.cz: Jak koupit Mikuláše a nenaletět

Jak koupit Mikuláše a nenaletět

Vitalia.cz: Žloutenka v Brně: Nakaženo bylo 400 lidí

Žloutenka v Brně: Nakaženo bylo 400 lidí

Lupa.cz: Avast po spojení s AVG propustí 700 lidí

Avast po spojení s AVG propustí 700 lidí

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

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

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

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

Podnikatel.cz: EET zvládneme, budou horší zákony

EET zvládneme, budou horší zákony

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET

Vitalia.cz: Baletky propagují zdravotní superpostel

Baletky propagují zdravotní superpostel

DigiZone.cz: Flix TV má set-top box s HEVC

Flix TV má set-top box s HEVC

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

Root.cz: Vypadl Google a rozbilo se toho hodně

Vypadl Google a rozbilo se toho hodně

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

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

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

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

EET: Totálně nezvládli metodologii projektu