Můžete to implementovat sami vytvořením mapování slovníku pthread_t
do std::string
a pak přiřaďte výsledek pthread_self() k názvu, který chcete přiřadit aktuálnímu vláknu. Všimněte si, že pokud to uděláte, budete muset použít mutex nebo jiné synchronizační primitivum, abyste zabránili více vláknům souběžně upravovat slovník (pokud to již vaše implementace slovníku nedělá za vás). Můžete také použít proměnné specifické pro vlákno (viz pthread_key_create, pthread_setspecific, pthread_getspecific a pthread_key_delete) k uložení názvu aktuálního vlákna; pokud to však uděláte, nebudete mít přístup k názvům jiných vláken (zatímco se slovníkem můžete iterovat všechny dvojice id/název vlákna z libovolného vlákna).
Od glibc v2.12 můžete použít pthread_setname_np
a pthread_getname_np
pro nastavení/získání názvu vlákna.
Tato rozhraní jsou k dispozici na několika dalších systémech POSIX (BSD, QNX, Mac) v různých mírně odlišných formách.
Nastavení názvu bude vypadat nějak takto:
#include <pthread.h> // or maybe <pthread_np.h> for some OSes
// Linux
int pthread_setname_np(pthread_t thread, const char *name);
// NetBSD: name + arg work like printf(name, arg)
int pthread_setname_np(pthread_t thread, const char *name, void *arg);
// FreeBSD & OpenBSD: function name is slightly different, and has no return value
void pthread_set_name_np(pthread_t tid, const char *name);
// Mac OS X: must be set from within the thread (can't specify thread ID)
int pthread_setname_np(const char*);
A jméno můžete získat zpět:
#include <pthread.h> // or <pthread_np.h> ?
// Linux, NetBSD:
int pthread_getname_np(pthread_t th, char *buf, size_t len);
// some implementations don't have a safe buffer (see MKS/IBM below)
int pthread_getname_np(pthread_t thread, const char **name);
int pthread_getname_np(pthread_t thread, char *name);
// FreeBSD & OpenBSD: dont' seem to have getname/get_name equivalent?
// but I'd imagine there's some other mechanism to read it directly for say gdb
// Mac OS X:
int pthread_getname_np(pthread_t, char*, size_t);
Jak vidíte, není to úplně přenosné mezi systémy POSIX, ale pokud mohu říci, napříč linuxem mělo by to být konzistentní. Kromě Mac OS X (kde to můžete udělat pouze z vlákna) lze ostatní alespoň jednoduše přizpůsobit pro kód napříč platformami.
Zdroje:
- glibc NEWS (zmiňuje nová rozhraní ve verzi 2.12)
- glibc nptl/ChangeLog (zmiňuje nová rozhraní ve verzi 2.12)
- MKS setname / getname
- IBM setname / getname
- Mac OS X od
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
- QNX setname / getname
- Pokud vidím, FreeBSD setname / no getname
- OpenBSD setname / no getname, pokud vidím
- NetBSD setname / getname
Použijte prctl(2)
funkce s volbou PR_SET_NAME
(viz dokumenty).
Všimněte si, že staré verze dokumentů jsou trochu matoucí. Říkají
Nastavte název procesu pro volající proces
ale protože vlákna jsou v Linuxu procesy s nízkou hmotností (LWP), jedno vlákno je v tomto případě jeden proces.
Název vlákna můžete vidět pomocí ps -o cmd
nebo pomocí:
cat /proc/$PID/task/$TID/comm
nebo mezi ()
z cat /proc/$PID/task/$TID/stat
:
4223 (kjournald) S 1 1 1 0...
nebo z GDB info threads
mezi dvojitými uvozovkami:
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84