刚好看到nginx设置进程title的源码,因此做一些总结。

linux进程实际是以argv[0]处的值来作为进程的title的,因此若需要修改进程的title只需要修改argv[0]处的值即可。

简单的方法就是直接将想要设置的title复制给argv[0]即可,如下示:

   1: #include <stdio.h>

   2: #include <stdlib.h>

   3: #include <string.h>

   4: #include <unistd.h>

   5:  

   6: extern char** environ;

   7:  

   8: int main(int argc, char* argv[])

   9: {

  10:     char s_title[] = "ymc title for simple way!";

  11:     size_t i_size = strlen(s_title);

  12:  

  13:     memcpy(argv[0], s_title, i_size);

  14:     argv[0][i_size] = '\0';

  15:     

  16:     while(1){

  17:         system("ps -ef|awk '$8 ~ /ymc/ {print $0}'");

  18:         sleep(10);

  19:     }

  20:  

  21:     return 0;

  22: }

运行结果为:

[root@localhost prc_title]# ./prc_title_simple 
root 19062 14675 0 20:17 pts/0 00:00:00 ymc title for simple way!
root 19062 14675 0 20:17 pts/0 00:00:00 ymc title for simple way!

但是这种方式是以破坏性的方式,进程的进程title的修改。由于程序的参数存储空间的后面紧跟的就是环境变量的存储位置,在不考虑参数的破坏性的情况下

过长的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 dos 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的迁移。下面是初始化函数

   1: //指向环境变量,默认的

   2: extern char **environ;

   3: //指向之前的用于存放参数及环境变量的空间的最后位置。

   4: static char *ngx_os_argv_last;

   5:  

   6: ngx_int_t

   7: ngx_init_setproctitle(ngx_log_t *log)

   8: {

   9:     u_char      *p;

  10:     size_t       size;

  11:     ngx_uint_t   i;

  12:  

  13:     size = 0;

  14:     //计算环境变量所用的总的空间的大小,然后以申请足够的空间用于存放环境变量

  15:     for (i = 0; environ[i]; i++) {

  16:         size += ngx_strlen(environ[i]) + 1;

  17:     }

  18:     //为环境就是分配空间

  19:     p = ngx_alloc(size, log);

  20:     if (p == NULL) {

  21:         return NGX_ERROR;

  22:     }

  23:     //下面开始计算前面用于存放环境变量的最后位置

  24:     ngx_os_argv_last = ngx_os_argv[0];

  25:     //首先计算参数的最后位置

  26:     for (i = 0; ngx_os_argv[i]; i++) {

  27:         if (ngx_os_argv_last == ngx_os_argv[i]) {

  28:             ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;

  29:         }

  30:     }

  31:     //再计算环境变量占用的最后位置,并完成环境变量的拷贝

  32:     for (i = 0; environ[i]; i++) {

  33:         if (ngx_os_argv_last == environ[i]) {

  34:  

  35:             size = ngx_strlen(environ[i]) + 1;

  36:             ngx_os_argv_last = environ[i] + size;

  37:  

  38:             ngx_cpystrn(p, (u_char *) environ[i], size);

  39:             environ[i] = (char *) p;

  40:             p += size;

  41:         }

  42:     }

  43:  

  44:     ngx_os_argv_last--;

  45:  

  46:     return NGX_OK;

  47: }

然后是具体的设置title的函数

   1: void

   2: ngx_setproctitle(char *title)

   3: {

   4:     u_char     *p;

   5:  

   6: #if (NGX_SOLARIS)

   7:  

   8:     ngx_int_t   i;

   9:     size_t      size;

  10:  

  11: #endif

  12:     

  13:     ngx_os_argv[1] = NULL;

  14:     //设置title,

  15:     p = ngx_cpystrn((u_char *) ngx_os_argv[0], (u_char *) "nginx: ",

  16:                     ngx_os_argv_last - ngx_os_argv[0]);

  17:  

  18:     p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p);

  19:  

  20: #if (NGX_SOLARIS)

  21:  

  22:     size = 0;

  23:  

  24:     for (i = 0; i < ngx_argc; i++) {

  25:         size += ngx_strlen(ngx_argv[i]) + 1;

  26:     }

  27:  

  28:     if (size > (size_t) ((char *) p - ngx_os_argv[0])) {

  29:  

  30:         /*

  31:          * ngx_setproctitle() is too rare operation so we use

  32:          * the non-optimized copies

  33:          */

  34:  

  35:         p = ngx_cpystrn(p, (u_char *) " (", ngx_os_argv_last - (char *) p);

  36:  

  37:         for (i = 0; i < ngx_argc; i++) {

  38:             p = ngx_cpystrn(p, (u_char *) ngx_argv[i],

  39:                             ngx_os_argv_last - (char *) p);

  40:             p = ngx_cpystrn(p, (u_char *) " ", ngx_os_argv_last - (char *) p);

  41:         }

  42:  

  43:         if (*(p - 1) == ' ') {

  44:             *(p - 1) = ')';

  45:         }

  46:     }

  47:  

  48: #endif

  49:  

  50:     if (ngx_os_argv_last - (char *) p) {

  51:         ngx_memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p);

  52:     }

  53:  

  54:     ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,

  55:                    "setproctitle: \"%s\"", ngx_os_argv[0]);

  56: }

最后就是根据nginx的思想的一个简单修改title的示例:

   1: #include <stdio.h>

   2: #include <stdlib.h>

   3: #include <string.h>

   4: #include <unistd.h>

   5:  

   6: extern char** environ;

   7:  

   8: void my_initproctitle(char* argv[], char** last);

   9: void my_setproctitle(char* argv[], char** last, char* title);

  10:  

  11: int main(int argc, char* argv[])

  12: {

  13:     char s_title[] = "ymc title ymc title";

  14:     char* p_last = NULL;

  15:  

  16:    my_initproctitle(argv, &p_last);

  17:    my_setproctitle(argv, &p_last, s_title);

  18:  

  19:     while(1)

  20:     {

  21:         system("ps -ef|awk '$8 ~ /ymc/ {print $0}'");

  22:         sleep(10);

  23:     }

  24:  

  25:     return 0;

  26: }

  27:  

  28: void my_initproctitle(char* argv[], char** last)

  29: {

  30:     int i = 0;

  31:     char* p_tmp = NULL;

  32:     size_t i_size = 0;

  33:  

  34:     for(i = 0; environ[i]; i++){

  35:         i_size += strlen(environ[i]) + 1;

  36:     }

  37:  

  38:     p_tmp = malloc(i_size);

  39:     if(p_tmp == NULL){

  40:         return ;

  41:     }

  42:  

  43:     *last = argv[0];

  44:     for(i = 0; argv[i]; i++){

  45:         *last += strlen(argv[i]) + 1;

  46:     }

  47:  

  48:     for(i = 0; environ[i]; i++){

  49:         i_size = strlen(environ[i]) + 1;

  50:         *last += i_size;

  51:  

  52:         strncpy(p_tmp, environ[i], i_size);

  53:         environ[i] = p_tmp;

  54:         p_tmp += i_size;

  55:     }

  56:  

  57:     (*last)--;

  58:  

  59:     return ;

  60:  

  61: }

  62:  

  63: void my_setproctitle(char* argv[], char** last, char* title)

  64: {

  65:     char* p_tmp = NULL;

  66:     /* argv[1] = NULL; */

  67:  

  68:     p_tmp = argv[0];

  69:     /* memset(p_tmp, 0, *last - p_tmp); */

  70:     strncpy(p_tmp, title, *last - p_tmp);

  71:  

  72:     return ;

  73: }

运行结果:

[root@localhost prc_title]# ./prc_title
root 19507 14675 0 20:33 pts/0 00:00:00 ymc title ymc title

这里还有个问题就是没考虑新的存储environ的空间的释放。

转载请注明出处:http://www.cnblogs.com/doop-ymc/p/3432184.html

nginx 设置进程title的更多相关文章

  1. 【nginx】【转】Nginx核心进程模型

    一.Nginx整体架构 正常执行中的nginx会有多个进程,最基本的有master process(监控进程,也叫做主进程)和woker process(工作进程),还可能有cache相关进程.   ...

  2. Nginx的进程模型及高可用方案(OpenResty)

    1. Nginx 进程模型简介 Nginx默认采用多进程工作方式,Nginx启动后,会运行一个master进程和多个worker进程.其中master充当整个进程组与用户的交互接口,同时对进程进行监护 ...

  3. nginx的进程模型

    nginx采用的也是大部分http服务器的做法,就是master,worker模型,一个master进程管理站个或者多个worker进程,基本的事件处理都是放在woker中,master负责一些全局初 ...

  4. [C#]使用 C# 代码实现拓扑排序 dotNet Core WEB程序使用 Nginx反向代理 C#里面获得应用程序的当前路径 关于Nginx设置端口号,在Asp.net 获取不到的,解决办法 .Net程序员 初学Ubuntu ,配置Nignix 夜深了,写了个JQuery的省市区三级级联效果

    [C#]使用 C# 代码实现拓扑排序   目录 0.参考资料 1.介绍 2.原理 3.实现 4.深度优先搜索实现 回到顶部 0.参考资料 尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用. ...

  5. 【Nginx】进程模型

    转自:网易博客 服务器的并发模型设计是网络编程中很关键的一个部分,服务器的并发量取决于两个因素,一个是提供服务的进程数量,另外一个是每个进程可同时处理的并发连接数量.相应的,服务器的并发模型也由两个部 ...

  6. nginx 设置反向代理

    一.多个路径指向同一ip的不同服务 参考地址:https://www.cnblogs.com/hanmk/p/9289069.html 编辑nginx.conf配置文件,新增加一个server模块,或 ...

  7. Nginx之进程间的通信机制(信号、信号量、文件锁)

    1. 信号 Nginx 在管理 master 进程和 worker 进程时大量使用了信号.Linux 定义的前 31 个信号是最常用的,Nginx 则通过重定义其中一些信号的处理方法来使用吸纳后,如接 ...

  8. Nginx之进程间的通信机制(Nginx频道)

    1. Nginx 频道 ngx_channel_t 频道是 Nginx master 进程与 worker 进程之间通信的常用工具,它是使用本机套接字实现的,即 socketpair 方法,它用于创建 ...

  9. Nginx之进程间的通信机制(共享内存、原子操作)

    1. 概述 Linux 提供了多种进程间传递消息的方式,如共享内存.套接字.管道.消息队列.信号等,而 Nginx 框架使用了 3 种传递消息的传递方式:共享内存.套接字.信号. 在进程间访问共享资源 ...

随机推荐

  1. LR的VG与Control之间的关系,并发的实质

    LR的VG与Control之间的关系,经过无数次的实验,搞清楚了现实意义的并发.传说每秒有几百,几千,几万用户并发,基本属于设想状态. 在一秒内处理多少个请求,完全在于服务器处理能力的强弱.这里需要强 ...

  2. string 转 int,int 转 string

    string str="12345"; int b=atoi(str.c_str()); 可以配合atof,转为double char buf[10]; sprintf(buf,  ...

  3. asp.net 基础

    前台HTML,javascript,后台C# 代码能不在后台写,就不在后台写 WebSite和WebApplication的区别 1)当改变后台代码时,WebApplication需重启浏览器或者重新 ...

  4. go mode

    https://github.com/dominikh/go-mode.el http://blog.altoros.com/golang-part-1-main-concepts-and-proje ...

  5. 【转】ethtool 命令详解

    命令描述: ethtool 是用于查询及设置网卡参数的命令. 使用概要:ethtool ethx       //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0.eth1等等etht ...

  6. UITextField和一个UILabel绑定 浅析

    转载自:http://fengdeng.github.io/blog/2016/01/22/rxswift-dao-di-%5B%3F%5D-ge-uitextfieldshi-ru-he-he-%5 ...

  7. c语言判断打开文件是否为空的方法

    void writeReslut2(char* caseName,double averageTime,double max, double min,int loops,int size){ fpos ...

  8. Boyer Moore算法(字符串匹配)

    上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ...

  9. Windows API 之 ReadProcessMemory

    ReadProcessMemory: BOOL WINAPI ReadProcessMemory( _In_ HANDLE hProcess, _In_ LPCVOID lpBaseAddress, ...

  10. android 没有main函数,怎么找到程序执行入口呢?以及activity主要生命周期的方法说明

    android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码之外生成的Activity,比如a ...