nginx学习---设置进程title(setproctitle)
来源:互联网 发布:手柄震动测试软件 编辑:程序博客网 时间:2024/06/05 16:53
nginx学习—设置进程title(setproctitle)
刚好看到nginx设置进程title的源码,因此做一些总结。
linux进程实际是以argv[0]处的值来作为进程的title的,因此若需要修改进程的title只需要修改argv[0]处的值即可。
简单的方法就是直接将想要设置的title复制给argv[0]即可,如下示:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> extern char** environ; int main(int argc, char* argv[]) { char s_title[] = "xiejian title for simple way!"; size_t i_size = strlen(s_title); memcpy(argv[0], s_title, i_size); argv[0][i_size] = '\0'; while(1){ system("ps -ef|awk '$8 ~ /xiejian/ {print $0}'"); sleep(10); }}
运行结果为:
但是这种方式是以破坏性的方式,进程的进程title的修改。由于程序的参数存储空间的后面紧跟的就是环境变量的存储位置,在不考虑参数的破坏性的情况下。
命令行参数argv和环境变量信息environ是在一块连续的内存中表示的,并且environ紧跟在argv后面。如下图:
由上图可知过长的title也会损坏环境变量environ的值。因此在nginx中,是将环境变量进行移位存储处理的。下面是nginx处理进程设置title的思路。
/* * To change the process title in Linux and Solaris we have to set argv[1] * to NULL and to copy the title to the same place where the argv[0] points to. * However, argv[0] may be too small to hold a new title. Fortunately, Linux * and Solaris store argv[] and environ[] one after another. So we should * ensure that is the continuous memory and then we allocate the new memory * for environ[] and copy it. After this we could use the memory starting * from argv[0] for our process title. * * The Solaris's standard /bin/ps does not show the changed process title. * You have to use "/usr/ucb/ps -w" instead. Besides, the UCB ps does not * show a new title if its length less than the origin command line length. * To avoid it we append to a new title the origin command line in the * parenthesis. */
然后由于nginx中考虑多进程的情况,因此他会在初始化时就完成environ的迁移。下面是初始化函数
//指向环境变量,默认的extern char **environ;//指向之前的用于存放参数及环境变量的空间的最后位置。static char *ngx_os_argv_last;ngx_int_tngx_init_setproctitle(ngx_log_t *log){ u_char *p; size_t size; ngx_uint_t i; size = 0;//计算环境变量所用的总的空间的大小,然后以申请足够的空间用于存放环境变量 for (i = 0; environ[i]; i++) { size += ngx_strlen(environ[i]) + 1; } //为环境就是分配空间 p = ngx_alloc(size, log); if (p == NULL) { return NGX_ERROR; } //下面开始计算前面用于存放环境变量的最后位置ngx_os_argv_last = ngx_os_argv[0];//首先计算参数的最后位置 for (i = 0; ngx_os_argv[i]; i++) { if (ngx_os_argv_last == ngx_os_argv[i]) { ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1; } } //再计算环境变量占用的最后位置,并完成环境变量的拷贝 for (i = 0; environ[i]; i++) { if (ngx_os_argv_last == environ[i]) { size = ngx_strlen(environ[i]) + 1; ngx_os_argv_last = environ[i] + size; ngx_cpystrn(p, (u_char *) environ[i], size); environ[i] = (char *) p; p += size; } } ngx_os_argv_last--; return NGX_OK;}
然后是具体的设置title的函数:
voidngx_setproctitle(char *title){ u_char *p;#if (NGX_SOLARIS) ngx_int_t i; size_t size;#endif ngx_os_argv[1] = NULL; p = ngx_cpystrn((u_char *) ngx_os_argv[0], (u_char *) "nginx: ", ngx_os_argv_last - ngx_os_argv[0]); p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p);#if (NGX_SOLARIS) size = 0; for (i = 0; i < ngx_argc; i++) { size += ngx_strlen(ngx_argv[i]) + 1; } if (size > (size_t) ((char *) p - ngx_os_argv[0])) { /* * ngx_setproctitle() is too rare operation so we use * the non-optimized copies */ p = ngx_cpystrn(p, (u_char *) " (", ngx_os_argv_last - (char *) p); for (i = 0; i < ngx_argc; i++) { p = ngx_cpystrn(p, (u_char *) ngx_argv[i], ngx_os_argv_last - (char *) p); p = ngx_cpystrn(p, (u_char *) " ", ngx_os_argv_last - (char *) p); } if (*(p - 1) == ' ') { *(p - 1) = ')'; } }#endif if (ngx_os_argv_last - (char *) p) { ngx_memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p); } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "setproctitle: \"%s\"", ngx_os_argv[0]);}
最后就是根据nginx的思想的一个简单修改title的示例:
#include <unistd.h> #include <stdio.h>#include <stdlib.h>#include <string.h>#define NGX_OK 0#define NGX_ERROR -1#define NGX_SETPROCTITLE_PAD '\0'typedef int ngx_int_t;typedef unsigned int ngx_uint_t;extern char **environ;static char *ngx_os_argv_last;int ngx_argc;char **ngx_os_argv;u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n){ if (n == 0) { return dst; } while (--n) { *dst = *src; if (*dst == '\0') { return dst; } dst++; src++; } *dst = '\0'; return dst;}ngx_int_tngx_init_setproctitle(){ u_char *p; size_t size; ngx_uint_t i; size = 0; for (i = 0; environ[i]; i++) { size += strlen(environ[i]) + 1; } p = malloc(size); if (p == NULL) { return NGX_ERROR; } ngx_os_argv_last = ngx_os_argv[0]; for (i = 0; ngx_os_argv[i]; i++) { if (ngx_os_argv_last == ngx_os_argv[i]) { ngx_os_argv_last = ngx_os_argv[i] + strlen(ngx_os_argv[i]) + 1; } } for (i = 0; environ[i]; i++) { if (ngx_os_argv_last == environ[i]) { size = strlen(environ[i]) + 1; ngx_os_argv_last = environ[i] + size; ngx_cpystrn(p, (u_char *) environ[i], size); environ[i] = (char *) p; p += size; } } ngx_os_argv_last--; return NGX_OK;}voidngx_setproctitle(char *title){ u_char *p; ngx_os_argv[1] = NULL; p = ngx_cpystrn((u_char *) ngx_os_argv[0], (u_char *) "nginx: ", ngx_os_argv_last - ngx_os_argv[0]); p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p); if (ngx_os_argv_last - (char *) p) { memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p); }}static ngx_int_tngx_save_argv(int argc, char *const *argv){ ngx_os_argv = (char **) argv; ngx_argc = argc; return NGX_OK;}int main(int argc, char *const *argv){ ngx_save_argv(argc,argv); ngx_init_setproctitle(); ngx_setproctitle("xiejian test"); while(1){ system("ps -ef|awk '$8 ~ /nginx/ {print $0}'"); sleep(10); } return (0); }
运行结果为:
阅读全文
0 0
- nginx学习---设置进程title(setproctitle)
- Linux修改进程名称(setproctitle())
- Linux修改进程名称(setproctitle())
- Linux修改进程名称(setproctitle())
- Linux修改进程名称(setproctitle())
- [redis] setproctitle.c实现 修改进程名称
- Linux C 修改进程名称(setproctitle())
- nginx 进程数设置
- nginx学习3——nginx进程
- nginx的守护进程学习
- document.title FIREFOX 设置 TITLE
- nginx的worker数目进程设置问题
- Flex设置标题title
- Flex 设置标题title
- Activity的title设置
- UIButton的title设置
- tabbar title设置
- navigationcontroller设置title字体
- Android UnsatisfiedLinkError: Couldn't load XXXfrom loader dalvik.system.PathClassLoader[DexPathLis
- QT QTableView表格左上角样式
- [Android]笔记15:自动完成文本框(AutoCompleteTextView)的功能与用法
- Cesium学习(2):Demo部署和运行
- IntelliJ IDEA快捷键说明(MAC版)
- nginx学习---设置进程title(setproctitle)
- spring大文件分块上传原理解析
- eclipse 创建maven项目设置默认jdk版本
- Bokeh库
- NKOJ-3697 乒乓比赛
- elasticsearch-5.5 安装以及基础入门
- 修改Linux下MySQL表名大小写敏感
- 查看崩溃日志
- 线程的阻塞、中断小结