一般来说,Linux 平台的 C/C++ 程序可以用 prctl() 或 pthreads 的 pthread_setname_np() 接口为一个线程设置线程名。prctl() 可以用于为当前线程设置线程名,pthread_setname_np() 则可以用于为当前进程的任意线程设置线程名。

prctl() 的函数声明如下:

       #include <sys/prctl.h>int prctl(int option, unsigned long arg2, unsigned long arg3,unsigned long arg4, unsigned long arg5);

pthread_setname_np() 的函数声明如下:

       #define _GNU_SOURCE             /* See feature_test_macros(7) */#include <pthread.h>int pthread_setname_np(pthread_t thread, const char *name);int pthread_getname_np(pthread_t thread,char *name, size_t len);

如果想要通过 prctl() 为其它线程设置线程名,一般需要先将线程名放在某个地方,然后在目标线程中拿到线程名并设下去。最常见的还是,在线程启动之前准备好线程名,新线程启动之后,立即设置线程名。比如,像下面这样:

#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <pthread.h>char *thread_name1 = nullptr;
char *thread_name2 = nullptr;void* thread1(void* arg) {prctl(PR_SET_NAME, thread_name1);while (1) {printf("thread1\n");sleep(1000);}
}void* thread2(void* arg) {while (1) {printf("thread2\n");sleep(1000);}
}int main() {pthread_t th1, th2;void* retval = NULL;thread_name1 = "THREAD1";pthread_create(&th1, NULL, thread1, NULL);pthread_create(&th2, NULL, thread2, NULL);printf("main thread\n");pthread_join(th1, &retval);pthread_join(th2, &retval);
}

曾经项目中遇到过一个设置线程名不生效的问题,最终同事查出来是因为设置的线程名太长导致的。

glibc 的 pthread_setname_np() 函数实现 (glibc 版本 2.34,代码位于 glibc-2.34/nptl/pthread_setname.c) 如下:

/* pthread_setname_np -- Set  thread name.  Linux versionCopyright (C) 2010-2021 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General Public License aspublished by the Free Software Foundation; either version 2.1 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with the GNU C Library; see the file COPYING.LIB.  Ifnot, see <https://www.gnu.org/licenses/>.  */#include <errno.h>
#include <fcntl.h>
#include <pthreadP.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/prctl.h>#include <not-cancel.h>int
__pthread_setname_np (pthread_t th, const char *name)
{const struct pthread *pd = (const struct pthread *) th;/* Unfortunately the kernel headers do not export the TASK_COMM_LENmacro.  So we have to define it here.  */
#define TASK_COMM_LEN 16size_t name_len = strlen (name);if (name_len >= TASK_COMM_LEN)return ERANGE;if (pd == THREAD_SELF)return __prctl (PR_SET_NAME, name) ? errno : 0;#define FMT "/proc/self/task/%u/comm"char fname[sizeof (FMT) + 8];sprintf (fname, FMT, (unsigned int) pd->tid);int fd = __open64_nocancel (fname, O_RDWR);if (fd == -1)return errno;int res = 0;ssize_t n = TEMP_FAILURE_RETRY (__write_nocancel (fd, name, name_len));if (n < 0)res = errno;else if (n != name_len)res = EIO;__close_nocancel_nostatus (fd);return res;
}
versioned_symbol (libc, __pthread_setname_np, pthread_setname_np,GLIBC_2_34);#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_12, GLIBC_2_34)
compat_symbol (libpthread,__pthread_setname_np, pthread_setname_np,GLIBC_2_12);
#endif

可以看到,当设置的线程名长度超过 16 个字符时,直接返回失败。当通过 pthread_setname_np() 为当前线程设置线程名时,通过调用 prctl() 实现,当给其它线程设置线程名时,则通过向 procfs 文件系统中,线程的 comm 文件中写入线程名来实现。

Linux 平台 C/C++ 代码中设置线程名相关推荐

  1. Android 中设置线程优先级的正确方式(2种方法)

    Android 中设置线程优先级的正确方式(2种方法) 在 Android 中,有两种常见的设置线程优先级的方式: 第一种,使用 Thread 类实例的 setPriority 方法,来设置线程优先级 ...

  2. Android如何在java代码中设置margin

    Android如何在java代码中设置margin,也就是组件与组件之间的间距. 代码中设置: LinearLayout.LayoutParams params = new LinearLayout. ...

  3. 1、代码中设置编码、编辑器中设置Python的编码

    1Python中文编码 1.1代码中设置编码 Python中默认的编码格式是ASCII格式,在没有修改编码格式时无法正确打印汉字,所以在读取中文的时候会报错. 解决办法为只要在文件开头加入 # -- ...

  4. java.library.path属性在代码中设置不生效问题

    http://www.blogjava.net/gembin/archive/2008/10/29/237377.html from http://daimojingdeyu.blogbus.com/ ...

  5. Android在代码中设置drawableLeft(Right/Top/Bottom)

    根据业务的需要,要在代码中设置控件的drawableLeft,drawableRight,drawableTop,drawableBottom属性. 我们知道在xml中设置的方法为: android: ...

  6. 详解Spring中的CharacterEncodingFilter--forceEncoding为true在java代码中设置失效--html设置编码无效...

    在项目中有很多让人头疼的问题,其中,编码问题位列其一,那么在Spring框架中是如何解决从页面传来的字符串的编码问题的呢?下面我们来看看Spring框架给我们提供过滤器CharacterEncodin ...

  7. android中在java代码中设置Button按钮的背景颜色

    android中在java代码中设置Button按钮的背景颜色 1.设置背景图片,图片来源于drawable: flightInfoPanel.setBackgroundDrawable(getRes ...

  8. 如何在Linux上的命令行中设置Google Chrome浏览器的代理设置?

    How to set Google Chrome's proxy settings in command line on Linux? I am using Google Chrome on Linu ...

  9. android 设置字体大小和不同颜色,Android代码中设置字体大小,字体颜色,显示两种颜色.倒计时效果...

    Android代码中设置字体大小,字体颜色,显示两种颜色 在xml文件中字体大小用的像素 android:id="@+id/uppaid_time" android:layout_ ...

最新文章

  1. ISA SERVER日志存放SQL SERVER中
  2. 60条令你大吃一惊的小常识,很有用
  3. 信息学奥赛一本通 1324:【例6.6】整数区间
  4. RDLC 报表参数、常量及常用表达式的使用方法(上)
  5. python外星人入侵游戏图片_外星人入侵,使用python开发的2D游戏
  6. springboot yml对于list列表配置方式
  7. NSArray的排序问题
  8. matlab积分器重置功能,MATLABSIMULINK积分器相关操作.docx
  9. Nvidia驱动支持的linux版本,NVIDIA首发OpenGL 3.1驱动 全面支持Linux
  10. 天地图 android 接口,天地图嵌入到Android手机中
  11. 常用ruby gem
  12. 【游戏推荐】癞子斗地主--OGEngine精品游戏推荐系列【一】
  13. 初学ue4#2 制作3d视角人物part2
  14. 硬件加速不支持的问题
  15. 使用cmd命令行实现百度云不限速下载
  16. 真实版的“北京爱情故事”
  17. JVM出现OOM的八种原因及解决办法
  18. 鼠标之父:恩格尔巴特于2013年7月3日去世
  19. android 换肤探索(一) 手把手做一个皮肤包
  20. 解密马云“永不放弃”字条的接头暗号

热门文章

  1. SpringCloud_Sell.sql
  2. 二叉树的遍历实现-2(三级)
  3. c语言 变量 定义 使用,C语言为什么要规定对所用到的变量要“先定义,后使用”...
  4. lambda 表达式中的 this 与普通情况下的 this 指向
  5. 哈希表-set/数组
  6. MongoEngine MongoDB 的 ORM 库
  7. 字符串与指针,数组的关系与用途
  8. 阿里云移动测试平台MQC移动测试沙龙第3期【北京站】
  9. 手动爬虫之流程笔记1(python3)
  10. 在 docker中 运行 mono /jexus server 并部署asp.net mvc站点