如何在Linux pthreads中设置线程的名称?

Ano*_*nym 57 c linux pthreads

有没有办法在Linux中设置线程的名称?

我的主要目的是在调试时提供帮助,如果通过例如公开这个名称也很好 /proc/$PID/task/$TID/...

drf*_*lat 103

从glibc v2.12开始,您可以使用pthread_setname_nppthread_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*);
Run Code Online (Sandbox Code Playgroud)

你可以得到这个名字:

#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);
Run Code Online (Sandbox Code Playgroud)

正如你可以看到它不是POSIX系统之间完全可移植的,但据我可以告诉对面的Linux应该是一致的.除了Mac OS X(你只能在线程内完成),其他的至少要适应跨平台代码.

资料来源:

  • @kralyk我认为在使用 gdb 或“top -H”进行调试时它会很有用 (3认同)

Aar*_*lla 31

使用prctl(2)带选项的功能PR_SET_NAME(请参阅文档).

请注意,文档有点令人困惑.他们说

设置调用进程的进程名称

但由于Linux上的线程是轻量级进程(LWP),因此在这种情况下,一个线程就是一个进程.

您可以使用ps -o cmd或查看线程名称:

cat /proc/$PID/task/$TID/comm
Run Code Online (Sandbox Code Playgroud)

或在之间()cat /proc/$PID/task/$TID/stat:

4223 (kjournald) S 1 1 1 0...
Run Code Online (Sandbox Code Playgroud)

或者从info threads双引号之间的GDB :

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

  • 请注意,实际的线程名称将位于/ proc/$ PID/tasks/$ TID/stat中 (3认同)
  • 为了完整起见,我将其留在此处,以免因更改主线程名称而陷入困境:https://lists.linuxfoundation.org/pipermail/bugme-new/2008-October/020065.html (2认同)

Mic*_*yan 6

您可以通过创建字典映射pthread_t来自己实现std::string,然后将pthread_self()的结果与要分配给当前线程的名称相关联.请注意,如果这样做,您将需要使用互斥或​​其他同步原语来防止多个线程同时修改字典(除非您的字典实现已经为您执行此操作).您还可以使用特定于线程的变量(请参阅pthread_key_create,pthread_setspecific,pthread_getspecificpthread_key_delete)以保存当前线程的名称; 但是,如果您这样做,您将无法访问其他线程的名称(而使用字典,您可以从任何线程迭代所有线程ID /名称对).

  • 请注意,此解决方案可跨Linux,Mac OS X以及符合Single UNIX Specification的所有系统移植.(Aaron Digulla发布的使用"prctl"的建议不是便携式的). (3认同)
  • 这似乎是一个非常糟糕的主意,人们不应该这样做. (2认同)
  • 你怎么能从APP外面看到它?比如ps,还是top? (2认同)