在开发实践中,有时候需要更改进程的名称(例如在fork出一堆子进程时,我们需要在top或者ps 的时候能区分父子进程,对其查看和管理)。很多人知道通过prctl系统调用可以修改进程名称,它的确能修改进程名称,但他有明确的长度限制,在我的linux环境下它最多支持15个字节的进程名,超长后就会被截断。
我们知道进程名是存在argv[0]中的,能否直接在代码中直接修改argv[0]的值来修改进程名呢?答案是可以的,但需要注意的是如果给出新名称过长,可能会超过argv[0]的原有的空间大小,这样就会覆盖argv[1]的内容。幸运的是在阅读nginx源码的时候发现在linux环境下 argv 和
环境变量 environ 在内存空间上是相邻的,这样可以就可以搞些小动作,将environ和argv[1]以及其后的参数保存到别的地方去,腾出这一整块的内存空间给argv[0]使用,这样就可以随心所欲的修改进程名称了,长度不再是问题。
参照nginx的源码,给出的demo如下:
- #include<stdio.h>
- #include<string.h>
- #include<unistd.h>
- #include<sys/prctl.h>
- #include<stdint.h>
- extern char **environ;
- char** pp_argv;
- char* pEnvLast = NULL;
- void backupEnv()
- {
- uint32_t i = 0;
- uint32_t envSize = 0;
- for (i = 0 ; environ[i] ; ++i)
- {
- envSize = envSize + strlen(environ[i]) + 1;
- }
- pEnvLast = environ[i-1] + strlen(environ[i-1]) + 1;
- char* pEnv = new char[envSize];
- //备份环境变量
- for (i = 0 ; environ[i] ; ++i)
- {
- strcpy(pEnv,environ[i]);
- pEnv = pEnv + strlen(environ[i]) + 1;
- environ[i] = pEnv;
- }
- }
- void setProcTitle(const char* title)
- {
- pp_argv[1] = NULL;
- strncpy(pp_argv[0],title,pEnvLast-pp_argv[0]);
- //如果进程名称比较短,可以直接使用prctl来修改
- //prctl(PR_SET_NAME,title);
- }
- int main(int argc, char* argv[])
- {
- if (2 != argc)
- {
- printf("usuage:%s newTitle\n",argv[0]);
- return 0;
- }
- pp_argv = (char**) argv;
- char procName[100];
- strcpy(procName,argv[1]);
- backupEnv();
- setProcTitle(procName);
-
- //休眠,便于通过top或者ps 观察进程名称
- sleep(20);
- return 0;
- }
阅读(3268) | 评论(0) | 转发(0) |