我发现了这个帖子 https://stackoverflow.com/questions/2369738/how-to-set-the-name-of-a-thread-in-linux-pthreads关于更改线程的名称。
我尝试过prctl()
and pthread_setname_np()
功能。两者都更改了名称ALL我的线程。换句话说,它似乎没有按预期工作。
I used:
pthread_setname_np(pthread_self(), "thread ONE");
and
pthread_setname_np(pthread_self(), "thread TWO");
根据哪个线程先运行,两个线程都会显示“线程一”或“线程二”。我期望其中一个是“线程一”,另一个是“线程二”。
难道我做错了什么?
正如 Tzig 在评论中提出的那样,我测试了 pthread_setname_np() 文档中所示的示例。但是,我需要使用至少两个线程进行测试,因此我将代码更改为具有线程 1 和线程 2。
默认情况下,我可以启动htop
并使用 F4 仅显示名称包括的线程/进程THREAD
(我还可以使用命令行使用不同的名称:./a.out MULTIFOO MULTIBAR
然后使用这个词MULTI
作为过滤器)。
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define NAMELEN 16
#define errExitEN(en, msg) \
do { errno = en; perror(msg); \
exit(EXIT_FAILURE); } while (0)
static void *
threadfunc(void *parm)
{
sleep(15); // allow main program to set the thread name
return NULL;
}
int
main(int argc, char **argv)
{
pthread_t thread1, thread2;
int rc;
char thread_name[NAMELEN];
rc = pthread_create(&thread1, NULL, threadfunc, NULL);
if (rc != 0)
errExitEN(rc, "pthread_create");
rc = pthread_create(&thread2, NULL, threadfunc, NULL);
if (rc != 0)
errExitEN(rc, "pthread_create");
// test name of thread1
//
rc = pthread_getname_np(thread1, thread_name, NAMELEN);
if (rc != 0)
errExitEN(rc, "pthread_getname_np");
printf("Created thread1. Default name is: %s\n", thread_name);
rc = pthread_setname_np(thread1, (argc > 1) ? argv[1] : "THREADFOO");
if (rc != 0)
errExitEN(rc, "pthread_setname_np");
sleep(2);
rc = pthread_getname_np(thread1, thread_name, NAMELEN);
if (rc != 0)
errExitEN(rc, "pthread_getname_np");
printf("The thread1 name after setting it is %s.\n", thread_name);
// test name of thread2
//
rc = pthread_getname_np(thread2, thread_name, NAMELEN);
if (rc != 0)
errExitEN(rc, "pthread_getname_np");
printf("Created thread2. Default name is: %s\n", thread_name);
rc = pthread_setname_np(thread2, (argc > 2) ? argv[2] : "THREADBAR");
if (rc != 0)
errExitEN(rc, "pthread_setname_np");
sleep(2);
rc = pthread_getname_np(thread2, thread_name, NAMELEN);
if (rc != 0)
errExitEN(rc, "pthread_getname_np");
printf("The thread2 name after setting it is %s.\n", thread_name);
// thread1 name changed too?
//
rc = pthread_getname_np(thread1, thread_name, NAMELEN);
if (rc != 0)
errExitEN(rc, "pthread_getname_np");
printf("The thread1 name after setting thread2 name is %s.\n", thread_name);
rc = pthread_join(thread1, NULL);
if (rc != 0)
errExitEN(rc, "pthread_join");
rc = pthread_join(thread2, NULL);
if (rc != 0)
errExitEN(rc, "pthread_join");
printf("Done\n");
exit(EXIT_SUCCESS);
}
P.S. There is a bug in the original:
rc = pthread_getname_np(thread, thread_name,
(argc > 2) ? atoi(argv[1]) : NAMELEN);
请注意,atoi()
uses argv[1]
代替argv[2]
。 (我已向手册页维护者报告了该错误。)
在我的示例中,我使用第二个参数作为第二个线程的名称,并始终使用NAMELEN
作为我的缓冲区的长度。我没有理由减少这个数额。
RESULTS:
正如预期的那样,pthread_getname_np()
作品。伟大的!
但是,那htop
or cat /proc/self/task/<tid>/comm
全部返回设置的姓氏。我猜这是 Linux 内核中的一个错误...但是,我的进程还有由 NVidia 驱动程序创建的其他线程,并且这些线程具有不同的名称。
以防万一,我尝试了中找到的功能Linux - 如何更改 C 中分叉进程的信息 https://stackoverflow.com/questions/5881556/linux-how-to-change-info-of-forked-processes-in-c这似乎是错误的,因为它说“fork()'ed”。但由于每个任务都有自己的条目/proc
...但我认为问题是线程与其主进程共享相同的内存,并且只有一个位置用于argv[0]
数据。换句话说,他们实施了一个pthread_setname_np()
哪个有效内部,但不会在工具中反映该名称,例如ps
and htop
.