Identifikační čísla vláken
Občas je důležité zjistit, jaké je identifikační číslo vlákna. To může zjistit funkce pthread_self(), která zjistí identifikační číslo volajícího vlákna. Toto číslo může být porovnáno s identifikačním číslem jiného vlákna, a to pomocí funkce pthread_equal().
Uvedené funkce mohou být užitečné, když je nutné zjistit, zda konkrétní vlákno odpovídá aktuálnímu vláknu. Pokud totiž vlákno zavolá funkcipthread_join() samo na sebe, vznikne chyba (funkce vrátí chybový kód EDEADLK). K ověření těchto skutečností můžete použít kód podobný tomuto:
if(!pthread_equal(pthread_self(), other_thread) pthread_join(other_thread, NULL);
Atributy vláken
Atributy vláken poskytují mechanismus pro detailní modifikaci jejich chování. Funkce pthread_create() má totiž argument, jenž je ukazatelem na objekt zvaný atributy vlákna. Pokud předáte prostřednictvím tohoto argumentu nulový ukazatel, použijí se ke konfiguraci implicitní atributy. Můžete však specifikovat jiné atributy, a definovat tak jiné chování vlákna. Při specifikaci atributů vlákna se postupuje podle následujících kroků:
- Vytvoříte objekt pthread_attr_t. Nejjednoduší způsob spočívá v tom, že použijete automatickou proměnnou tohoto typu.
- Zavoláte funkci pthread_attr_init(), které předáte ukazatel na zmíněný objekt prostřednictvím argumentu. Tak inicializujete atributy na implicitní hodnoty.
- Objekt s atributy modifikujete podle potřeby.
- Ukazatel na objekt s atributy předáte funkci pthread_create() při jejím volání.
- Objekt s atributy uvolníte pmocí funkce pthread_attr_destroy(). Samotná proměnná pthread_attr_t však není dealokována. Můžete ji znovu inicializovat pomocí funkce pthread_attr_init().
Jediný objekt s atributy vlákna může být použit k inicializaci několika vláken. Není nutné objekt s atributy uchovávat poté, co jsou požadovaná vlákna vytvořena.
Pro většinu aplikací v Linuxu se obvykle využívá pouze jeden atribut vlákna (ostatní mají význam pro speciální aplikce, např. takové, které běží v reálném čase). Tento atribut se nazývá stav odloučení. Každé vlákno může být vytvořeno jako spojitelné nebo odloučené. Spojitelné vlákno, podobně jako proces, není automaticky uklizeno operačním systémem, když ukončí svou činnost. Místo toho zůstane v systému v podobě blízké procesu zombie, dokud jiné vlákno nezavolá funkci pthread_join(), aby získalo jeho návratovou hodnotu. Pak jsou systémové zdroje vlákna uvolněny. Odloučené vlákno je naopak automaticky odklizeno, jakmile ukončí svou činnost. Z tohoto důvodu s ním nemůže synchronizovat svou činnost žádné jiné vlákno prostřednictvím funkce pthread_join(). Žádné jiné vlákno také nemůže získat návratovou hodnotu odloučeného vlákna.
K nastavení odloučeného stavu atributu vlákna použijte funkci pthread_attr_setdetachstate(). Prvním argumentem je ukazatel na objekt atributů vlákna a druhým je požadovaný stav. Protože stav odloučení není implicitní, je tato funkce nutná jen pro vlákna odloučená. Jako druhý argument používejte jméno jméno PTHREAD_CREATE_DETACHED.
#include <pthread.h>
void *thread_function(void *thread_arg)
{
/* Vlakno zde provadi nejake operace */
}
int main()
{
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thread, &attr, &thread_function, NULL);
pthread_attr_destroy(&attr);
/* Program dale pokracuje v realizaci kodu */
return(0);
}
Dokonce i v případě, že je vlákno vytvořeno ve spojitelném stavu, může být později konvertováno na odloučené vlákno. Jakmile je však vlákno jednou definováno jako odloučené, nemůže být konvertováno na spojitelné.
Zrušení vlákna
Za normálních okolností končí vlákno buď návratem z funkce vlákna, nebo voláním funkce pthread_exit(). Je ovšem možné požadovat, aby jedno vlákno ukončilo jiné. Takovému procesu se říká zrušení (cancelling) vlákna.
Ke zrušení vlákna slouží funkce pthread_cancel(), které se předává jako parametr identifikační číslo vlákna, jež se má zrušit. Zrušené vlákno může být později spojeno (pokud se nejedná o odloučené vlákno). Návratová hodnota zrušeného vlákna je speciální – PTHREAD_CANCELED.
Tak to by bylo pro dnešek vše. Příště si povíme o tom, jak obhospodařit kód vlákna, který se NESMÍ zrušit.