通过nginx学习linux进程名的修改

目录

  • 1. 缘起
  • 2. 背景知识
  • 3. 源码分析
    • 3.1 准备工作
    • 3.2 设置进程名字

1. 缘起

  在运行nginx的时候,用ps查看nginx的进程信息,可能的输出如下:

root      42169    3105  0 16:51 ?        00:00:00 nginx: master process ./objs/nginx
root      42170   42169  0 16:51 ?        00:00:00 nginx: worker process
root      42171   42169  0 16:51 ?        00:00:00 nginx: worker process

  显示的最后一列进程名字非常清晰,有master process, worker process,一目了然。可是如果我们自己写一个程序,运行起来的时候则完全不是那样,显示的就是运行这个程序的命令行,如果是一个多进程的程序,则不太好区分不同的进程到底是干什么用的。那么就来研究一下nginx到底是怎么做的吧。

2. 背景知识

  通过ps或者top看到的linux进程实际上就是操作系统给当前进程分配的命令行缓冲区中的内容,在c程序中就是 main(int argc, char *const *argv)函数的argv指向的地址。这是一个连续的地址,存放了命令行参数列表,而命令行参数后面则是环境变换缓冲区。如下图:
在这里插入图片描述

  可以看到,命令行和环境变量两个缓冲区是前后相邻的。我们需要通过修改命令行参数对应的缓冲区内容来修改进程名字信息,但是需要考虑的一个问题是,因为命令行参数和环境变量的缓存是前后相邻的,如果新修改的进程名字的信息比原先的长,就可能出现覆盖后面的环境变量的问题,导致程序故障。因此,我们需要在修改进程名的时候对环境变量部分另外再分配一段内存来存储,来避开这个问题。

  接下来看看nginx的实现代码,学会了nginx的处理逻辑,我们完全可以今后拿过来在自己的其他程序中来使用了。

3. 源码分析

  nginx的这部分源码只存在于os/unix/ngx_setproctitle.c中,由于windows系统是不能支持修改进程名的,所以在os/win32目录中没有类似的实现。它的实现很简单,分为两个函数,第一个函数用来做准备工作,给环境变量挪到一个新分配的位置;第二个函数才真正设置进程名。

3.1 准备工作

ngx_int_t
ngx_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_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;
}

以上代码逻辑非常简单明了,就是给环境变量缓冲区挪了个位置。

3.2 设置进程名字

void
ngx_setproctitle(char *title)
{u_char     *p;#if (NGX_SOLARIS)ngx_int_t   i;size_t      size;#endif/* 将命令行参数的第1个元素设置为空,表示将进程名后面的命令行参数全部忽略掉 */ngx_os_argv[1] = NULL;/* 将命令行参数的第0个元素指向的地址设置为想要的进程名title,以下分为两次拷贝,第一次写入前缀nginx: 第二次才写入传入的参数title*/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);/* solaris 部分的解析这里略过不看了 */
#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/* 将命令行缓冲区后面多出来的空间填充空格,我感觉这行判断语句代码有点小毛病,如果p > ngx_os_argv_last呢,当然实际应该不太会发生这种情况*/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]);
}

   好了,以上就是对如何设置进程名字的一个分析和学习的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2776014.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Java图形化界面编程—— 基本组件和对话框 笔记

2.5 AWT中常用组件 2.5.1 基本组件 组件名功能ButtonButtonCanvas用于绘图的画布Checkbox复选框组件&#xff08;也可当做单选框组件使用&#xff09;CheckboxGroup选项组&#xff0c;用于将多个Checkbox 组件组合成一组&#xff0c; 一组 Checkbox 组件将只有一个可以 被选中…

供应链|Managemeng Science 论文解读:数据驱动下联合定价和库存控制的近似方法 (一)

编者按 本次解读的文章发表于 Management Science&#xff0c;原文信息&#xff1a;Hanzhang Qin, David Simchi-Levi, Li Wang (2022) Data-Driven Approximation Schemes for Joint Pricing and Inventory Control Models. https://doi.org/10.1287/mnsc.2021.4212 文章在数…

代码随想录算法训练营第四十六天(动态规划篇)|01背包(滚动数组方法)

01背包&#xff08;滚动数组方法&#xff09; 学习资料&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff08;和上次一样&#xff09;&#xff1a;题目页面 (kamacoder.com) 思路 使用一维滚动数组代替二维数组。二维数组的解法记录在&#xff1a;代码随想录算…

最新的 Ivanti SSRF 零日漏洞正在被大规模利用

Bleeping Computer 网站消息&#xff0c;安全研究员发现 Ivanti Connect Secure 和 Ivanti Policy Secure 服务器端请求伪造 (SSRF) 漏洞&#xff08;CVE-2024-21893 &#xff09;正在被多个威胁攻击者大规模利用。 2024 年 1 月 31 日&#xff0c;Ivanti 首次就网关 SAML 组件…

【工作学习 day04】 9. uniapp 页面和组件的生命周期

问题描述 uniapp常用的有&#xff1a;页面和组件&#xff0c;并且页面和组件各自有各自的生命周期函数&#xff0c;那么在页面/组件请求数据时&#xff0c;是用created呢&#xff0c;还是用onLoad呢&#xff1f; 先说结论: 组件使用组件的生命周期&#xff0c;页面使用页面的…

机器学习11-前馈神经网络识别手写数字1.0

在这个示例中&#xff0c;使用的神经网络是一个简单的全连接前馈神经网络&#xff0c;也称为多层感知器&#xff08;Multilayer Perceptron&#xff0c;MLP&#xff09;。这个神经网络由几个关键组件构成&#xff1a; 1. 输入层 输入层接收输入数据&#xff0c;这里是一个 28x…

双侧条形图绘制教程

写在前面 双侧条形图在我们的文章中也是比较常见的&#xff0c;那么这样的图形是如何绘制的呢&#xff1f; 以及它使用的数据类型是什么呢&#xff1f; 这些都是我们在绘制图形前需要掌握的&#xff0c;至少我们知道绘图的数据集如何准备&#xff0c;这样才踏出第一步。 今天…

基于Linux操作系统的Docker容器安装MySQL随笔

1、在Linux上安装Docker容器 cd /etc/yum.repos.d/ curl -O https://download.docker.com/linux/centos/docker-ce.repo sed -i s/$releasever/8/g docker-ce.repo yum install -y docker-ce 2、修改Docker默认镜像仓库&#xff0c;然后启动Docker容器 sudo mkdir -p /etc/do…

Javaweb之SpringBootWeb案例之异常处理功能的详细解析

3. 异常处理 3.1 当前问题 登录功能和登录校验功能我们都实现了&#xff0c;下面我们学习下今天最后一块技术点&#xff1a;异常处理。首先我们先来看一下系统出现异常之后会发生什么现象&#xff0c;再来介绍异常处理的方案。 我们打开浏览器&#xff0c;访问系统中的新增部…

独家完整版!SpringBoot动态定时任务来了!

执行定时任务的线程池配置类 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTas…

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…

雨云2h2g香港二区云服务器测评(纯测评)

购买并且重装好系统后&#xff0c;来itdog去ping一下看看延迟怎么样。&#xff08;香港无移动屏蔽&#xff09;&#xff1a; 然后&#xff0c;我们来做一个线路路由测试&#xff08;去回程路由测试&#xff09;。&#xff08;雨云香港服务器IP不是原生IP&#xff0c;而是广播IP…

【Spring】Spring 对 Ioc 的实现

一、Ioc 控制反转 控制反转是一种思想 控制反转是为了降低程序耦合度&#xff0c;提高程序扩展力&#xff0c;达到 OCP 原则&#xff0c;达到 DIP 原则 控制反转&#xff0c;反转的是什么&#xff1f; 将对象的创建权利交出去&#xff0c;交给第三方容器负责 将对象和对象之…

会声会影绿幕抠图操作方法 会声会影绿幕抠图有绿色残边 绿幕抠图视频有绿边怎么处理 抖音怎么剪辑视频 视频剪辑软件推荐

科幻片里真的存在怪兽吗&#xff1f;外太空的画面是直接将演员放入太空拍摄的吗?其实这些不切实际的画面是通过绿幕拍摄实现的。你只需要在绿幕前拍一段太空漫步的视频&#xff0c;再利用会声会影的抠图功能就能实现&#xff01;如果你还不会绿幕抠图&#xff0c;我今天就手把…

Vue.js2+Cesium1.103.0 十五、绘制视锥,并可实时调整视锥姿态

Vue.js2Cesium1.103.0 十五、绘制视锥&#xff0c;并可实时调整视锥姿态 Demo <template><divid"cesium-container"style"width: 100%; height: 100%;"/> </template><script> /* eslint-disable no-undef */ /* eslint-disable …

微信小程序的图片色彩分析,窃取网络图片的主色调

1、安装 Mini App Color Thief 包 包括下载包&#xff0c;简单使用都有&#xff0c;之前写了&#xff0c;这里就不写了 网址&#xff1a;微信小程序的图片色彩分析&#xff0c;窃取主色调&#xff0c;调色板-CSDN博客 2、 问题和解决方案 问题&#xff1a;由于我们的窃取图片的…

娅奴服饰:行至云深处,问计新零售

编辑&#xff1a;阿冒 设计&#xff1a;沐由 大浪壮美&#xff0c;时尚前行。 作为广东省首批特色小镇创建示范点&#xff0c;以及粤港澳大湾区唯一的特色时尚小镇&#xff0c;大浪时尚小镇云集了700余家服装及配套企业&#xff0c;涌动着蓬勃的生机与无尽的活力。 国内知名的“…

API网关架构设计与实现的经验总结与实践

API网关是现代微服务架构中的重要组件&#xff0c;它充当了前端和后端微服务之间的中介。本文将介绍API网关的架构设计原则和实现方法&#xff0c;以帮助开发人员更好地理解和应用这些技术。 1. 什么是API网关&#xff1f; - 解释了API网关的基本概念和作用&#xff0c;以及…

API接口访问鉴权设计和实现的经验总结

API接口访问鉴权是保护API资源安全的重要措施。本文总结了一些常见的API接口访问鉴权设计和实现方法&#xff0c;以帮助开发人员更好地理解和应用这些技术。 1. 什么是API接口访问鉴权&#xff1f; - 解释了API接口访问鉴权的基本概念和作用&#xff0c;以及为什么需要对A…

如何轻松恢复已删除/未保存的 Word 文档

经过几个小时的编写和编辑后&#xff0c;您的计算机决定崩溃&#xff0c;或者您不小心删除了您一直在努力处理的同一个文件。听起来像一场噩梦&#xff0c;对吧&#xff1f;不幸的是&#xff0c;任何人都可能遇到这种情况&#xff0c;这就是为什么我们整理了这份经过尝试和测试…