Как установить имя потока в Linux pthreads?

Есть ли способ установить имя потока в Linux?

Моя основная цель - это было бы полезно при отладке, а также было бы хорошо, если бы это имя было выставлено, например, через /proc/$PID/task/$TID/...

3 ответа

Решение

Использовать prctl(2) функция с опцией PR_SET_NAME (см. документы).

Обратите внимание, что документы немного сбивают с толку. Они говорят

Установите имя процесса для вызывающего процесса

но поскольку потоки - это процессы с малым весом в Linux, в этом случае один поток - это один процесс.

Вы можете увидеть название потока с ps -o cmd или с:

cat /proc/$PID/task/$TID/comm

или между () из cat /proc/$PID/task/$TID/stat:

4223 (kjournald) S 1 1 1 0...

или из ГБД info threads между двойными кавычками:

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  

Начиная с 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's 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 (где вы можете сделать это только из потока), другие, по крайней мере, просты в адаптации для кроссплатформенного кода.

Источники:

Вы можете реализовать это самостоятельно, создав словарь сопоставления pthread_t в std::string, а затем свяжите результат pthread_self() с именем, которое вы хотите назначить текущему потоку. Обратите внимание, что если вы сделаете это, вам нужно будет использовать мьютекс или другой примитив синхронизации, чтобы предотвратить одновременное изменение словаря несколькими потоками (если только ваша словарная реализация уже не делает это для вас). Вы также можете использовать переменные, специфичные для потока (см. Pthread_key_create, pthread_setspecific, pthread_getspecific и pthread_key_delete), чтобы сохранить имя текущего потока; однако, если вы это сделаете, вы не сможете получить доступ к именам других потоков (тогда как со словарем вы можете перебирать все пары идентификаторов / имен потоков из любого потока).

Другие вопросы по тегам