Как установить имя потока в Linux pthreads? - PullRequest
56 голосов
/ 03 марта 2010

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

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

Ответы [ 3 ]

98 голосов
/ 03 ноября 2011

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

Источники:

29 голосов
/ 03 марта 2010

Используйте функцию 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...

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

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  
5 голосов
/ 03 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...