linu中使用prctl函數爲線程指定名字

轉載自:http://www.itwendao.com/article/detail/365516.html

一、前言

    有時候我們通過fork()、pthread_create()創建出來的新任務其名字和創建任務的parent是一樣的,如果有需要,該如何修改這些新創建任務的名字呢?

    有辦法,用proctl()函數來實現。這個函數可用來對任務進行控制,其具體情況如下所示:

#include <sys/prctl.h>

int prctl(int option, unsigned long arg2, unsigned long arg3,
                 unsigned long arg4, unsigned long arg5);
    其中第一個參數“option”用來指明prctl()對線程(也可以稱爲任務)實施的具體的控制行爲,其可選的值在<linux/protl.h>文件中定義;而"option"後面參數的值意義需要根據"option"來定。
    對於"option"的選項有很多,我們這裏只關注的是"PR_SET_NAME"這個選項,其他的選項這裏就不一一給出了,感興趣的可以參考: prctl(2)
    當入參"option"值爲"PR_SET_NAME"時,prctl()會爲 調用此函數的 線程設置新名字,新名字設置爲參數(char *)arg2。其中,線程名字的參數arg2字符串的最大長度爲16 bytes(包括字符串終止符)。如果arg2長度超過16 bytes,它將會被截斷爲16 bytes。
    除了使用“PR_SET_NAME”參數可以設置線程名字外,另外一個函數pthread_setname_np()也可以實現此功能。設置完成後我們可以通過線程的tid來查看它的新名字:
cat /proc/pid/task/[tid]/comm
    上面的"pid"表示這個線程所屬線程組leader的"pid","tid"則是調用prctl()函數的線程id。

二、代碼

    瞭解了proctl()的使用後我們看看具體的例子:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdarg.h>		/* asked by va_star and va_end */
#include <sys/prctl.h>  /* asked by PR_SET_NAME */

void die(const char *fmt, ...);
int * thread1(void *arg);
int * thread2(void *arg);
int * thread3(void *arg);
int thread_create(void);
void process_create(int num_proc);

int main(int argc,char *argv[]){
	printf("will create threads\n");
	thread_create();
	while(1){sleep(1);}
}

void die(const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	fflush(stdout);
	fflush(stderr);
	exit(1);
}

void process_create(int num_proc) {
	pid_t pid;
	int i = 0;
	char childname[][10] = {
		"process-1",
		"process-2",
		"process-3",
		"process-4",
		"process-5",
		"process-6",
	};
	if (num_proc < 1)
		die("num of proc must > 1\n");
	while(i < num_proc) {
		if ((pid = fork()) < 0) 
			die("fork failed\n");
		if (0 == pid) {
			prctl(PR_SET_NAME, childname[i], NULL, NULL, NULL); 
			while(1);
			exit(0);
		}
		i++;
	}
}

int * thread1(void *arg)
{
	prctl(PR_SET_NAME, "THREAD1");
	printf("thread id is %lu.\n", (unsigned long)pthread_self());
		while(1){sleep(5);};
        return NULL;
}

int * thread2(void *arg)
{
	prctl(PR_SET_NAME,"THREAD2");
        printf("thread id is %lu.\n", (unsigned long)pthread_self());
		while(1){sleep(5);};
        return NULL;
}

int * thread3(void *arg)
{	
	prctl(PR_SET_NAME, "THREAD3");
	char command[128]= {0};
	process_create(5);		/* create 5 processes */
	printf("thread id is %lu.\n",(unsigned long)pthread_self());
	while(1){sleep(5);};
	return NULL;
}

int thread_create(void)
{
	pthread_t id1, id2, id3;
	printf("Main thread id is %lu \n", (unsigned long)pthread_self());
	if(!pthread_create(&id1, NULL, (void *)thread1, NULL))	{
		printf("thread 1 succed!\n");
	}
	if(!pthread_create(&id2, NULL, (void *)thread2, NULL))	{
		printf("thread 2 succed!\n");
	}
	if(!pthread_create(&id3, NULL, (void *)thread3, NULL))	{
		printf("thread 3 succed!\n");
	}
}

三、代碼分析

    上面的例子中創建來三個線程,並通過prctl(PR_SET_NAME,....)分別將名字設置爲THREAD1/THREAD2/THREAD3;接着THREAD3又創建來5個子進程,同樣,通過prctl(PR_SET_NAME,....)函數這些子進程將自己的名字分別設置爲"process-1" ~ "process-5"。

    可以通過如下命令進行編譯:

gcc -pthread -o prctl_name prctl_name.c
    編譯完成後生成可執行文件prctl_name ,然後運行 ./prctl_name &,   並在終端中通過 "ps -L"來查看結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章