Na jakém základě bych se tedy měl rozhodnout, zda bych měl použít pthread_self orgettid k určení, které vlákno spouští funkci?
Vždy byste měli používat pthread_self()
kdykoli chcete ve své aplikaci identifikovat vlákno. gettid()
může být používané pro určité účely a pokud víte, že je to Linux. Například gettid()
lze použít k získání semínka pro konkrétní semeno vlákna (používá se v srand()
).
Oba jsou nepřenosné.
Není to tak úplně pravda. gettid()
není přenosný, protože jde o funkci specifickou pro Linux. Ale pthread_self()
je přenosný, pokud neučiníte žádné předpoklady o jeho reprezentaci.
Například následující je ne přenosný.
printf("Thread ID is: %ld", (long) pthread_self());
protože neexistuje žádná záruka, že cokoli pthread_self()
bude nějaké celé číslo. Ale
pthread_t my_tid; //filled elsewhere
pthread_t tid = pthread_self();
if( pthread_equal(my_tid, tid) ) {
/* do stuff */
}
je plně přenosný.
První není přenosný, protože předpokládá toto ID vlákna je celé číslo, zatímco to druhé není.
Proč existují dvě různé funkce pro získání ID vlákna?
Nejsou to dva různé způsoby, jak získat stejnou hodnotu. Jedna (pthread_self()
je poskytována knihovnou vláken (pthreads), zatímco druhá (gettid()
je funkce specifická pro OS. Jiný operační systém může poskytovat jiné rozhraní/systémové volání pro získání ID vlákna podobné gettid()
. Nemůžete se tedy spolehnout na gettid()
v přenosné aplikaci.
pthread_self() returns the process-wide unique pthread-id.
gettid() vrací (specifické pro implementaci pthread) celosystémové jedinečné ID vlákna (v Linuxu).
the TID(thread id) returned by gettid() is unique inside a process
Ano.
(or inside a program with multiple processes,
Ano.
inside a process, different thread has different thread id.
Ano.
the TID returned by pthread_self() is unique across processes,
Ne.
different thread has different TID on the same machine at the same time.
Ano ve stejném procesu, Ne v celém počítači.
Vzhledem k tomu, že gettid() je specifický pro Linux, a proto není přenosný, jediný způsob, jak systém široce identifikovat pthread, je použít jeho (systémově jedinečné) ID nadřazeného procesu vrácené getpid() spolu s jeho (pro celý proces jedinečný) pthread- id vrácené pthread_self().
Toto je zajímavá studie o rozdílu mezi konceptuálními terminologie a skutečné softwarové entity (které patří do specifických softwarových abstrakcí).
Nejprve věnujte pozornost typům z těchto dvou hovorů.
pid_t gettid(void);
pthread_t pthread_self(void);
Jedna je pid_t
a druhý je pthread_t
. Oba tyto odkazují na společnou pojmovou entitu nazvanou thread
, ale různé typy naznačují, že se jedná o dva různé software entities
. Jsou to různé reprezentace thread id
a dává smysl v rámci softwarové abstrakce, která jej zahrnuje. Takže pthread_t
dává smysl pouze v rámci abstrakce podporované pthread
balíček a pid_t
dává smysl v rámci abstrakce, která tento typ zahrnuje (tj. systémová volání Linuxu, která se zabývají pid_t
).
Měli byste používat správný typ na základě kontextu. Použijte pthread_t
v kontextu, který vyžaduje typ pthread_t
a pid_t
v kontextu, který vyžaduje pid_t
- bez ohledu na to, že mohou odkazovat na stejné vlákno.
Každý z těchto kontextů má předepsanou syntaxi pro srovnání a rovnost. pid_t
lze přímo porovnat pomocí ==
operátor, zatímco pthread_t
musí být porovnáno vyvoláním pthread_equal
.
Důvodem této duální reprezentace / softwarové abstrakce je pthread
knihovna je přenosná knihovna vláken, kterou lze implementovat na různé operační systémy. Různé implementace pthread
knihovna zaručuje, že thread id
typ bude vždy pthread_t
. Tato vlákna mohou být pod mapou na konkrétní operační systém thread entity
jehož identifikátor OS závisí na operačním systému (např. pro Linux je to pid_t
; pro Windows je to DWORD
).
Takže i když se základní implementace může lišit od OS k OS, kód napsaný proti pthread
abstrakce zůstává přenosná napříč OS (pokud se omezíte na pthread
abstrakce).