Anda dapat mengimplementasikannya sendiri dengan membuat pemetaan kamus pthread_t
ke std::string
, lalu kaitkan hasil pthread_self() dengan nama yang ingin Anda tetapkan ke utas saat ini. Perhatikan bahwa, jika Anda melakukannya, Anda perlu menggunakan mutex atau primitif sinkronisasi lainnya untuk mencegah banyak utas memodifikasi kamus secara bersamaan (kecuali implementasi kamus Anda sudah melakukan ini untuk Anda). Anda juga dapat menggunakan variabel khusus utas (lihat pthread_key_create, pthread_setspecific, pthread_getspecific, dan pthread_key_delete) untuk menyimpan nama utas saat ini; namun, Anda tidak akan dapat mengakses nama utas lain jika melakukannya (sedangkan, dengan kamus, Anda dapat mengulangi semua pasangan id/nama utas dari utas mana pun).
Pada glibc v2.12, Anda dapat menggunakan pthread_setname_np
dan pthread_getname_np
untuk menyetel/mendapatkan nama utas.
Antarmuka ini tersedia di beberapa sistem POSIX lainnya (BSD, QNX, Mac) dalam berbagai bentuk yang sedikit berbeda.
Menetapkan nama akan menjadi seperti ini:
#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*);
Dan Anda bisa mendapatkan kembali namanya:
#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);
Seperti yang Anda lihat, ini tidak sepenuhnya portabel di antara sistem POSIX, tetapi sejauh yang saya tahu di linux itu harus konsisten. Selain Mac OS X (di mana Anda hanya dapat melakukannya dari dalam utas), yang lain setidaknya mudah diadaptasi untuk kode lintas platform.
Sumber:
- glibc NEWS (menyebutkan antarmuka baru di 2.12)
- glibc nptl/ChangeLog (menyebutkan antarmuka baru di 2.12)
- MKS setname / getname
- IBM setname / getname
- Mac OS X dari
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
- QNX setname / getname
- Setname FreeBSD / tidak ada getname sejauh yang saya bisa lihat
- OpenBSD setname / no getname sejauh yang saya bisa lihat
- Setname / getname NetBSD
Gunakan prctl(2)
berfungsi dengan opsi PR_SET_NAME
(lihat dokumen).
Perhatikan bahwa dokumen versi lama agak membingungkan. Kata mereka
Tetapkan nama proses untuk proses pemanggilan
tetapi karena utas adalah proses ringan (LWP) di Linux, satu utas adalah satu proses dalam kasus ini.
Anda dapat melihat nama utas dengan ps -o cmd
atau dengan:
cat /proc/$PID/task/$TID/comm
atau di antara ()
dari cat /proc/$PID/task/$TID/stat
:
4223 (kjournald) S 1 1 1 0...
atau dari GDB info threads
antara tanda kutip ganda:
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84