Есть ли способ установить имя потока в Linux?
Моя основная цель - это было бы полезно при отладке, а также приятно, если бы это имя было открыто через, например, /proc/$PID/task/$TID/...
Есть ли способ установить имя потока в Linux?
Моя основная цель - это было бы полезно при отладке, а также приятно, если бы это имя было открыто через, например, /proc/$PID/task/$TID/...
Используйте функцию prctl(2)
с опцией PR_SET_NAME
(см. документы).
Обратите внимание, что документы немного запутывают. Говорят,
Задайте имя процесса для вызывающего процесса
но поскольку потоки - это легкие процессы (LWP) в Linux, один поток - это один процесс в этом случае.
Вы можете увидеть имя потока с помощью ps -o cmd
или в /proc/$PID/stat
между ()
:
4223 (kjournald) S 1 1 1 0...
Как и в glibc v2.12, вы можете использовать pthread_setname_np
и pthread_getname_np
для установки/получения имени потока.
Эти интерфейсы доступны в нескольких других системах POSIX (BSD, QNX, Mac) в различных немного разных форматах.
Настройка имени будет выглядеть примерно так:
#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*);
И вы можете вернуть имя:
#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 some other mechanism to read it directly for say gdb
// Mac OS X:
int pthread_getname_np(pthread_t, char*, size_t);
Как вы можете видеть, он не полностью переносится между системами POSIX, но, насколько я могу судить по Linux, он должен быть последовательным. Помимо Mac OS X (где вы можете делать это только из потока), другие, по крайней мере, легко адаптируются для кросс-платформенного кода.
Источники:
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
Вы можете реализовать это самостоятельно, создав сопоставление словаря pthread_t
до std::string
, а затем связать результат pthread_self() с именем, которое вы хотите назначить текущему потоку. Обратите внимание: если вы это сделаете, вам нужно будет использовать мьютекс или другой примитив синхронизации, чтобы предотвратить одновременное изменение нескольких потоков в словаре (если только ваша реализация словаря уже делает это для вас). Вы также можете использовать переменные, зависящие от потока (см. pthread_key_create, pthread_setspecific, pthread_getspecific и pthread_key_delete), чтобы сохранить имя текущего потока; однако вы не сможете получить доступ к именам других потоков, если вы это сделаете (тогда как со словарем вы можете перебирать все пары id/name потока из любого потока).