twemproxy源码分析2——守护进程的创建
twemproxy源码中关于守护进程的创建实现得比较标准,先贴出代码来,然后结合一些资料来分析和列举一些实现守护进程的常用方法,不过不得不说twemproxy的实现确实是不错的,注释都写在了代码中,直接上代码吧:
static rstatus_t
nc_daemonize(int dump_core)
{
rstatus_t status;
pid_t pid, sid;
int fd; /*
* 先fork出一个子进程,把主进程关闭了
*/
pid = fork();
switch (pid) {
case -:
log_error("fork() failed: %s", strerror(errno));
return NC_ERROR; case :
break; default:
/* parent terminates */
_exit();
} /* 1st child continues and becomes the session leader */
/*
* 新fork出的子进程不可能是一个进程组的组长,这就避免了setsid函数调用的失败
* 在调用了setsid函数后该进程就成为新的会话组长和新的进程组长
* 并与原来的登录会话、进程组、控制终端脱离
*/
sid = setsid();
if (sid < ) {
log_error("setsid() failed: %s", strerror(errno));
return NC_ERROR;
} /*
* 处理SIGCHLD信号,内核在子进程结束时不会产生僵尸进程
*/
if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
log_error("signal(SIGHUP, SIG_IGN) failed: %s", strerror(errno));
return NC_ERROR;
} /*
* 再一次fork的原因是之前的子进程虽然已经脱离了控制终端,该子进程已经成为无终端的会话组长。
* 但它可以重新申请打开一个控制终端,可以通过使进程不再成为会话组长来禁止进程重新打开控制终端
*/
pid = fork();
switch (pid) {
case -:
log_error("fork() failed: %s", strerror(errno));
return NC_ERROR; case :
break; default:
/* 1st child terminates */
_exit();
} /* 2nd child continues */ /* change working directory */
/*
* 切换工作目录
*/
if (dump_core == ) {
status = chdir("/");
if (status < ) {
log_error("chdir(\"/\") failed: %s", strerror(errno));
return NC_ERROR;
}
} /* clear file mode creation mask */
/*
* 重设权限掩码
* 进程从创建它的父进程那里继承了文件创建掩码,它可能修改守护进程所创建的文件的存取位。
*/
umask(); /* redirect stdin, stdout and stderr to "/dev/null" */
/*
* 重定向描述符
*/
fd = open("/dev/null", O_RDWR);
if (fd < ) {
log_error("open(\"/dev/null\") failed: %s", strerror(errno));
return NC_ERROR;
} status = dup2(fd, STDIN_FILENO);
if (status < ) {
log_error("dup2(%d, STDIN) failed: %s", fd, strerror(errno));
close(fd);
return NC_ERROR;
} status = dup2(fd, STDOUT_FILENO);
if (status < ) {
log_error("dup2(%d, STDOUT) failed: %s", fd, strerror(errno));
close(fd);
return NC_ERROR;
} status = dup2(fd, STDERR_FILENO);
if (status < ) {
log_error("dup2(%d, STDERR) failed: %s", fd, strerror(errno));
close(fd);
return NC_ERROR;
} if (fd > STDERR_FILENO) {
status = close(fd);
if (status < ) {
log_error("close(%d) failed: %s", fd, strerror(errno));
return NC_ERROR;
}
} return NC_OK;
}
关于各种ID,先贴上一个图,后面再解释
twemproxy源码分析2——守护进程的创建的更多相关文章
- v76.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式 | 百篇博客分析OpenHarmony源码
百篇博客分析|本篇为:(共享内存篇) | 进程间最快通讯方式 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) | 同样 ...
- Spark源码分析(三)-TaskScheduler创建
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3879151.html 在SparkContext创建过程中会调用createTaskScheduler函 ...
- Spring源码分析(十八)创建bean
本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 目录 一.创建bean的实例 1. autowireConstructor 2 ...
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
- twemproxy源码分析1——入口函数及启动过程
最近工作中需要写一个一致性哈希的代理,在网上找到了twemproxy,结合网上资料先学习一下源码. 一.Twemproxy简介 Twemproxy是memcache与redis的代理,由twitter ...
- nova-api源码分析(WSGI server的创建及启动)
源码版本:H版 一.前奏 nova api本身作为一个WSGI服务器,对外提供HTTP请求服务,对内调用nova的其他模块响应相应的HTTP请求.分为两大部分,一是服务器本身的启动与运行,一是加载的a ...
- Spark源码分析(二)-SparkContext创建
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3872785.html SparkContext是应用启动时创建的Spark上下文对象,是一个重要的入口 ...
- twemproxy源码分析
twemproxy是twitter开源的redis/memcached 代理,数据分片提供取模,一致性哈希等手段,维护和后端server的长连接,自动踢除server,恢复server,提供专门的状态 ...
- mybatis源码分析(1)-----sqlSessionFactory创建
1. 首先了解一下mybatis,包含核心jar ,以及spring相关jar. <!-- Mybatis相关组件 --> <dependency> <groupId&g ...
随机推荐
- codeforces#277.5 C. Given Length and Sum of Digits
C. Given Length and Sum of Digits... time limit per test 1 second memory limit per test 256 megabyte ...
- iOS:iOS开发系列–打造自己的“美图秀秀”(中)
来源: KenshinCui 链接:http://www.cnblogs.com/kenshincui/p/3959951.html 其他状态设置 常用的图形上下文状态设置上面基本都用到了,我们不再一 ...
- utf8汉字编码16进制对照(转载)
utf8汉字编码16进制对照 GB Unicode UTF-8 Chinese CharacterCode code# Code (coded in UTF-8)D2BB 4E00 E4 B8 80 ...
- java源码阅读Observable(观察者模式)
1类签名和简介 package java.util; public class Observable Observable是Java内置的观察者模式中的主题类(没错,是类不是接口),和其对应的观察者接 ...
- 从0x00到0xFF的含义以及二进制到10进制的转换(转)
转载自: http://www.cnblogs.com/brice/p/5343322.html 对于二进制来说,8位二进制我们称之为一个字节,二进制的表达范围值是从0b00000000-0b1111 ...
- CocoSourcesCS 3
CocoSourcesCS 3 /*---------------------------------------------------------------------- Compiler Ge ...
- Win7如何重建桌面图标缓存
[已解决] windows7快捷方式图标丢失的解决方案(已解决) windows7快捷方式图标丢失的解决方案转自:http://iso1.com/2010/01/14/how-to-restore-w ...
- swift 使用匿名函数初始化属性
swift 使用匿名函数初始化属性 匿名函数格式: { //代码体 }() 大括号是定义函数体的,小括号()是调用函数体的. 为什么不写一个函数然后调用函数呢?为何用匿名函数呢? 主要还是代码的简洁性 ...
- Spring中AOP的理解
1.AOP的概念 AOP(AspectOriented Programming,面向切面编程)指的是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下个程序动态统一添加功能的一种技术.AOP ...
- 算法笔记_102:蓝桥杯练习 算法提高 快乐司机(Java)
目录 1问题描述 2 解决方案 1 问题描述 问题描述 "嘟嘟嘟嘟嘟嘟 喇叭响 我是汽车小司机 我是小司机 我为祖国运输忙 运输忙" 这是儿歌“快乐的小司机”.话说现在当司机光 ...