有没有办法在 Linux 中设置线程的名称?
我的主要目的是在调试时更加方便,并且如果该名称通过例如 /proc/$PID/task/$TID/...
公开,那就更好了。
从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_set_name_np()
的意义是什么? - kralyktop -H
中会很有用。 - Thirupathi Thangavelvoid * arg
参数代表什么吗?我知道它是一个指针,但不确定这里的"argument used with name"是什么意思。我可以传递nullptr
吗?为什么可以或者为什么不可以? - undefined使用prctl(2)
函数,并选择选项PR_SET_NAME
(请参阅文档)。请注意,旧版本的文档有点令人困惑。它们说:
设置调用进程的进程名称
但是在Linux上,线程是轻量级进程(LWP),因此在这种情况下,一个线程就是一个进程。
您可以使用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
/proc
目录列表中看不到它们,线程仍可通过/proc/$TID
访问(因为基本上与进程相同)。 - ephemient/proc/$PID/task/$TID/stat
(tasks上没有s)。 - Andrew Wagner/proc/
目录清单中未列出,但如果你访问 /proc/$TID/
,仍然可以获取线程的信息。 - Craig McQueenpthread_t
映射到 std::string
的字典,并将 pthread_self() 的结果与您想要分配给当前线程的名称相关联,来自行实现此操作。请注意,如果这样做,您需要使用互斥锁或其他同步原语来防止多个线程同时修改字典(除非您的字典实现已经为您完成此操作)。您也可以使用线程特定变量(请参见pthread_key_create、pthread_setspecific、pthread_getspecific和pthread_key_delete),以保存当前线程的名称;但是,如果这样做,您将无法访问其他线程的名称(而使用字典,则可以从任何线程迭代所有线程ID/名称对)。_Thread_local
(自 C11 起)。这样编译器就可以为您完成繁重的工作。还有一个 thread_local
宏(使用与 C++11 相同的名称) - Alexis Wilke
/proc/self/comm
文件中的名称。或者它会复制上次设置的名称,这与没有名称一样无用。直接写入comm文件是允许的,并且对于所有工具(如htop和ps)都可以正常工作。 - Alexis Wilke