本文主要是prctl函数的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
 点击查看使用工具及版本  
              
                          Windows         windows11                  Ubuntu         Ubuntu16.04的64位版本                    VMware® Workstation 16 Pro         16.2.3 build-19376536                    SecureCRT         Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日                    开发板         正点原子 i.MX6ULL Linux阿尔法开发板                    uboot         NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)                    linux内核         linux-4.15(NXP官方提供)                    STM32开发板         正点原子战舰V3(STM32F103ZET6)        
               
             点击查看本文参考资料  
              
             点击查看相关文件下载  
              
            一、prctl() 函数 在 linux 下可以使用 man  2 prctl 命令查看该函数的帮助手册,也可以访问这里:prctl(2) - Linux manual page (man7.org) 。
1 2 3 4 5 #include  <sys/prctl.h>  int  prctl (int  option, unsigned  long  arg2, unsigned  long  arg3, unsigned  long  arg4, unsigned  long  arg5) ;
【函数说明】 该函数是一个系统调用指令,它是为进程制定而设计的,明确的选择取决于option。
【函数参数】 
option : int 类型,表示操作类型,具体有哪些类型,我们可以看 linux 内核源码中的 include/uapi/linux/prctl.h 文件。  
arg2、arg3、arg4和arg5 :unsigned long类型,这些就可以看手册了,不同的选项有不同的含义, 
 
【返回值】  int 类型,这个比较长,就看文档吧,哈哈哈。
【使用格式】 none
【注意事项】  none 
二、函数应用 为什么要说介绍这个函数?对于我自己来说,我是因为看到它可以设置线程的名称,可以很方便的查看我们的线程是否还在运行。
1. 线程使用实例 1.1 看不到线程信息?  点击查看实例  
              
              1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include  <stdio.h>    #include  <pthread.h>  #include  <unistd.h>   void  *thread1 (void  *arg) ;void  *thread2 (void  *arg) ;int  main (int  argc, char  *argv[]) { 	int  ret; 	pthread_t  tid1, tid2; 	ret = pthread_create(&tid1, NULL , thread1, NULL ); 	printf ("This is threadMutex1 thread create,ret=%d,tid1=%lu\n" , ret, tid1); 	ret = pthread_create(&tid2, NULL , thread2, NULL ); 	printf ("This is threadMutex2 thread create,ret=%d,tid2=%lu\n" , ret, tid2); 	while (1 ) 	{ 		sleep(1 ); 	} 	return  0 ; } void  *thread1 (void  *arg) { 	pthread_detach(pthread_self()); 	while (1 ) 	{ 		sleep(1 ); 	} 	pthread_exit("thread1 exit!" ); } void  *thread2 (void  *arg) { 	pthread_detach(pthread_self()); 	while (1 ) 	{ 		sleep(1 ); 	} 	pthread_exit("thread2 exit!" ); } 
 
            在上边的实例代码中,我们创建两个线程,然后我们在线程中什么也不做,我们编译程序:
1 gcc main.c -Wall -lpthread 
然后我们在后台运行这个进程(&就表示在后台运行这个进程):
然后我们会看看到屏幕上有两行输出:
1 2 This is threadMutex1 thread create,ret=0,tid1=140490243557120 This is threadMutex2 thread create,ret=0,tid2=140490235164416 
随后就什么现象都没有了,我们的进程在运行吗?创建的两条线程在运行吗?
我们使用ps命令来查看一下,在很多实际linux系统的根文件系统,其实并不会像ubuntu桌面版这样支持具有如此多参数的ps命令,一般我们在开发板上使用的根文件系统都是经过裁剪,所以这里我们使用最基础的命令来查看:
1 2 3 4 5 hk@vm:~/6temp/test$ ps    PID TTY          TIME CMD  54694 pts/22   00:00:00 bash  58091 pts/22   00:00:00 a.out  58109 pts/22   00:00:00 ps 
可以看到我们的进程 a.out 依然在运行,那线程呢,我们可以使用 -T 参数来查看进程以及线程?
1 2 3 4 5 6 7 hk@vm:~/6temp/test$ ps -T    PID   SPID TTY          TIME CMD  54694  54694 pts/22   00:00:00 bash  58091  58091 pts/22   00:00:00 a.out  58091  58092 pts/22   00:00:00 a.out  58091  58093 pts/22   00:00:00 a.out  58118  58118 pts/22   00:00:00 ps 
我们发现,有3个a.out,哪个是thread1,哪个是thread2?一眼看过去我们只能看到他们的PID和SPID,我们其实可以通过SPID来区分不同的线程,但是把,我自己是没有查过这个SPID是与创建线程的时候的tid究竟有没有联系,所以这个时候上边的prctl函数就起到了重要作用。
1.2 线程命名 在linux内核源码的 include/uapi/linux/prctl.h 文件中,定义的选项有这么一个:
我们查阅文档可以知道这个参数可以用于设定线程的名称:
PR_SET_NAME (since Linux 2.6.9)
 
翻译过来大概的意思就是,使用(char *) arg2指向的位置中的值可以设置调用线程的名称。该名称最多可以有16个字节长,包括终止空字节。(如果字符串的长度,包括结束空字节,超过16字节,字符串将被截断。)这个属性可以通过pthread_setname_np(3)设置,也可以使用pthread_getname_np(3)检索。该属性同样可以通过/proc/self/task/[tid]/comm访问,其中tid是调用线程的名称。
于是我们修改例子如下:
 点击查看详情  
              
              1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include  <stdio.h>    #include  <pthread.h>  #include  <unistd.h>   #include  <sys/prctl.h>  void  *thread1 (void  *arg) ;void  *thread2 (void  *arg) ;int  main (int  argc, char  *argv[]) { 	int  ret; 	pthread_t  tid1, tid2; 	ret = pthread_create(&tid1, NULL , thread1, NULL ); 	printf ("This is threadMutex1 thread create,ret=%d,tid1=%lu\n" , ret, tid1); 	ret = pthread_create(&tid2, NULL , thread2, NULL ); 	printf ("This is threadMutex2 thread create,ret=%d,tid2=%lu\n" , ret, tid2); 	while (1 ) 	{ 		sleep(1 ); 	} 	return  0 ; } void  *thread1 (void  *arg) { 	pthread_detach(pthread_self()); 	char  * thread1_name  = "thread1" ; 	prctl(PR_SET_NAME, (unsigned  long )thread1_name); 	while (1 ) 	{ 		sleep(1 ); 	} 	pthread_exit("thread1 exit!" ); } void  *thread2 (void  *arg) { 	pthread_detach(pthread_self()); 	char  * thread2_name  = "thread2" ; 	prctl(PR_SET_NAME, (unsigned  long )thread2_name); 	while (1 ) 	{ 		sleep(1 ); 	} 	pthread_exit("thread2 exit!" ); } 
 
            像上边一样,我们同样编译吗,并在后台运行:
1 2 gcc main.c -Wall -lpthread ./a.out & 
然后我们看一下现在的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 hk@vm:~/6temp/test$ ps    PID TTY          TIME CMD  57544 pts/23   00:00:00 bash  58948 pts/23   00:00:00 main_process  58970 pts/23   00:00:00 ps hk@vm:~$ ps -T    PID   SPID TTY          TIME CMD   2401   2401 pts/19   00:00:00 bash   8950   8950 pts/19   00:00:00 gedit   8950   8951 pts/19   00:00:00 gmain   8950   8952 pts/19   00:00:00 gdbus   8950   8953 pts/19   00:00:00 dconf worker   9001   9001 pts/19   00:00:00 a.out   9001   9002 pts/19   00:00:00 thread1   9001   9003 pts/19   00:00:00 thread2   9004   9004 pts/19   00:00:00 ps 
我们发现,我们的进程为a.out,下边有两个名为thread1和thread2的东西,它们前边的PID与进程a.out是一致的,这就是我们创建的两个线程。
2. 设置进程名字?  点击查看详情  
              
              1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include  <stdio.h>    #include  <unistd.h>   #include  <sys/prctl.h>  int  main (int  argc, char  *argv[]) { 	int  ret;      	char  * main_name  = "main_process" ; 	prctl(PR_SET_NAME, (unsigned  long )main_name);      	while (1 ) 	{ 		sleep(1 ); 	} 	return  0 ; } 
 
            像上边一样,我们同样编译吗,并在后台运行:
1 2 gcc main.c -Wall -lpthread ./a.out & 
然后我们看一下现在的情况:
1 2 3 4 5 hk@vm:~$ ps -T    PID   SPID TTY          TIME CMD   9077   9077 pts/1    00:00:00 bash   9106   9106 pts/1    00:00:00 main_process   9107   9107 pts/1    00:00:00 ps 
可以看到我们的进程名字不再是a.out了,变成了我们设置的值。