-
Vytvořte oddělené vlákno, když víte, že na něj nebudete chtít čekat s
pthread_join()
. Jedinou výhodou výkonu je to, že když se odpojené vlákno ukončí, jeho prostředky mohou být uvolněny okamžitě, aniž by bylo nutné čekat na připojení vlákna, než budou prostředky uvolněny. -
Je „legální“ nepřipojit se k připojitelnému vláknu; ale obvykle to není vhodné, protože (jak již bylo uvedeno výše) zdroje nebudou uvolněny, dokud nebude vlákno připojeno, takže pokud se k němu nepřipojíte, zůstanou svázané po neomezenou dobu (dokud se program neskončí).
Kdy mám vytvořit vlákno jako oddělené, hned od začátku?
Kdykoli je aplikaci jedno, kdy se vlákno dokončí, a nezajímá se ani o návratovou hodnotu vlákna (vlákno může sdělit hodnotu zpět jinému vláknu/aplikaci prostřednictvím pthread_exit
).
Například v aplikačním modelu klient-server může server vytvořit nové vlákno pro zpracování každého požadavku. Ale samotný server se nestará o návratovou hodnotu vlákna. V takovém případě má smysl vytvořit oddělené vlákna.
Jediné, co musí server zajistit, je dokončení aktuálně zpracovávaných požadavků. Což může udělat pouhým opuštěním hlavního vlákna bez ukončení celého programu/aplikace. Když skončí poslední vlákno v procesu, aplikace/program se přirozeně ukončí.
Pseudokód může vypadat takto:
/* A server application */
void process(void *arg)
{
/* Detach self. */
pthread_detach(pthread_self());
/* process a client request. */
pthread_exit(NULL);
}
int main(void)
{
while (not_done) {
pthread_t t_id;
errno = pthread_create(&t_id, NULL, process, NULL);
if (errno) perror("pthread_create:");
}
/* There may be pending requests at this point. */
/* Just exit the main thread - not the whole program - so that remaining
requests that may still be processed can continue. */
pthread_exit(NULL);
}
Dalším příkladem může být démon nebo vlákno loggeru, které protokoluje některé informace v pravidelných intervalech tak dlouho, dokud aplikace běží.
Nabízí nějakou výkonnostní výhodu oproti připojitelnému vláknu?
Pokud jde o výkon, mezi připojitelnými není žádný rozdíl vlákna vs oddělené vlákna. Jediný rozdíl je v tom, že u oddělených vláken jsou jejich prostředky (jako je zásobník vláken a jakákoli přidružená paměť haldy atd. – přesně to, co tyto „zdroje“ tvoří, specifické pro implementaci).
Je legální neprovádět pthread_join() na připojitelném (ve výchozím nastavení) vláknu?
Ano, je legální nepřipojit se k vláknu. pthread_join
je pouze pohodlná funkce, kterou v žádném případě není nutné používat, pokud to nepotřebujete. Pamatujte však, že vytvořená vlákna jsou připojitelná vlákna ve výchozím nastavení.
Příkladem, kdy se můžete chtít připojit, je, když vlákna dělají „kus“ práce, která je mezi ně rozdělena. V takovém případě byste před pokračováním měli zkontrolovat, zda jsou všechna vlákna dokončena. Dobrým příkladem je paralelismus farmy úloh.
Nebo by takové vlákno mělo vždy před pthread_exit()ing používat funkci odpojit()?
Není nutné. Často se ale budete chtít rozhodnout, zda chcete připojit se nebo oddělené vlákno v době vytvoření.
Všimněte si, že zatímco oddělitelné vlákno lze vytvořit nastavením atributu PTHREAD_CREATE_DETACHED
s voláním na pthread_attr_setdetachstate
vlákno se může rozhodnout, že se kdykoli odpojí, např. s pthread_detach(pthread_self())
. Také vlákno, které má ID vlákna (pthread_t
) jiného vlákna lze odpojit pomocí pthread_detach(thread_id);
.