C语言 如何在 Linux pthreads 中设置线程的名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2369738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set the name of a thread in Linux pthreads?
提问by Anonym
Is there any way of setting the name of a thread in Linux?
有没有办法在 Linux 中设置线程的名称?
My main purpose is it would be helpful while debugging, and also nice if that name was exposed through e.g. /proc/$PID/task/$TID/...
我的主要目的是在调试时会很有帮助,如果该名称通过例如公开也很好 /proc/$PID/task/$TID/...
采纳答案by Aaron Digulla
Use the prctl(2)function with the option PR_SET_NAME(see the docs).
使用prctl(2)带有选项的函数PR_SET_NAME(请参阅文档)。
Note that old versions of the docs are a bit confusing. They say
请注意,旧版本的文档有点令人困惑。他们说
Set the process name for the calling process
为调用进程设置进程名称
but since threads are light weight processes (LWP) on Linux, one thread is one process in this case.
但由于线程是 Linux 上的轻量级进程 (LWP),因此在这种情况下,一个线程就是一个进程。
You can see the thread name with ps -o cmdor with:
您可以使用ps -o cmd或来查看线程名称:
cat /proc/$PID/task/$TID/comm
or in between the ()of cat /proc/$PID/task/$TID/stat:
或在之间()的cat /proc/$PID/task/$TID/stat:
4223 (kjournald) S 1 1 1 0...
or from GDB info threadsbetween double quotes:
或来自info threads双引号之间的GDB :
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
回答by drfrogsplat
As of glibc v2.12, you can use pthread_setname_npand pthread_getname_npto set/get the thread name.
从 glibc v2.12 开始,您可以使用pthread_setname_np和pthread_getname_np来设置/获取线程名称。
These interfaces are available on a few other POSIX systems (BSD, QNX, Mac) in various slightly different forms.
这些接口在其他一些 POSIX 系统(BSD、QNX、Mac)上以各种稍微不同的形式提供。
Setting the name will be something like this:
设置名称将是这样的:
#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*);
And you can get the name back:
您可以取回名称:
#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);
As you can see it's not completely portable between POSIX systems, but as far as I can tell across linuxit should be consistent. Apart from Mac OS X (where you can only do it from within the thread), the others are at least simple to adapt for cross-platform code.
正如你可以看到它不是POSIX系统之间完全可移植的,但据我可以告诉对面的Linux应该是一致的。除了 Mac OS X(你只能在线程内完成),其他的至少很容易适应跨平台代码。
Sources:
资料来源:
- glibc NEWS(mentions new interfaces in 2.12)
- glibc nptl/ChangeLog(mentions new interfaces in 2.12)
- MKS setname/ getname
- IBM setname/ getname
- Mac OS X from
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h - QNX setname/ getname
- FreeBSD setname/ no getname as far as i can see
- OpenBSD setname/ no getname as far as i can see
- NetBSD setname/ getname
回答by Michael Aaron Safyan
You can implement this yourself by creating a dictionary mapping pthread_tto std::string, and then associate the result of pthread_self()with the name that you want to assign to the current thread. Note that, if you do that, you will need to use a mutex or other synchronization primitive to prevent multiple threads from concurrently modifying the dictionary (unless your dictionary implementation already does this for you). You could also use thread-specific variables (see pthread_key_create, pthread_setspecific, pthread_getspecific, and pthread_key_delete) in order to save the name of the current thread; however, you won't be able to access the names of other threads if you do that (whereas, with a dictionary, you can iterate over all thread id/name pairs from any thread).
您可以通过创建映射pthread_t到的字典来自己实现std::string,然后将pthread_self()的结果与您要分配给当前线程的名称相关联。请注意,如果您这样做,您将需要使用互斥锁或其他同步原语来防止多个线程同时修改字典(除非您的字典实现已经为您执行此操作)。您还可以使用特定于线程的变量(请参阅pthread_key_create、pthread_setspecific、pthread_getspecific和pthread_key_delete) 以保存当前线程的名称;但是,如果这样做,您将无法访问其他线程的名称(而使用字典,您可以遍历来自任何线程的所有线程 ID/名称对)。

