php守护进程创建和简要分析
守护进程可
- 由系统启动脚本 /etc/rc.local
- crontab任务,
- 用户shell
方式运行
进程守护化基本步骤
- 1.创建子进程,终止父进程 (pcntl_fork,exit)
- 2.在子进程中创建新会话 (posix_setsid)
- 3.改变工作目录(默认继承了父进程的当前工作目录) (chdir('/'))
- 4.重设文件掩码(默认继承了父进程的) (umask(0) 改变当前的umask为最宽松掩码)
- 5.关闭文件描述符(默认继承了父进程打开的文件描述符) (fclose 关闭已打开的文件描述符)
daemon.php
<?php
echo posix_getpid().PHP_EOL;
$childs = [];
$worker_num = 3;
//daemon();
for ($i = 0; $i < $worker_num; $i++) {
fork();
}
while (count($childs)) {
if (($exit_id = pcntl_wait($status)) > 0) {
$signo = pcntl_wtermsig($status);
unset($childs[$exit_id]);
}
if (count($childs) < $childs) {
fork();
}
}
function daemon()
{
$pid = pcntl_fork();
if ($pid < 0) die("fork err");
if ($pid == 0) {
if (posix_setsid() <= 0) {
die("setsid err!");
}
if (chdir('/') === false) {
die("change dir err");
}
umask(0);
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
} else {
exit();
}
}
function fork()
{
global $childs;
$pid = pcntl_fork();
if ($pid < 0) die("fork err");
if ($pid == 0) {
$child_pid = posix_getpid();
while (true) {
sleep(10);
}
} else {
$parent_pid = posix_getpid();
$childs[$pid] = $pid;
}
}
分析
不执行daeon函数时
[root@hkui ~]# pstree -p|grep php
|-sshd(3169)-+-sshd(10101)---bash(10103)---php(10609)-+-php(10610)
| | |-php(10611)
| | `-php(10612)
[root@hkui ~]# ps --sid 10103 -o pid,ppid,pgid,sid
PID PPID PGID SID
10103 10101 10103 10103
10609 10103 10609 10103
10610 10609 10609 10103
10611 10609 10609 10103
10612 10609 10609 10103
[root@hkui ~]# ps --pid 10101 -o pid,ppid,pgid,sid
PID PPID PGID SID
10101 3169 10101 10101
[root@hkui ~]# ps --pid 3169 -o pid,ppid,pgid,sid
PID PPID PGID SID
3169 1 3169 3169
------------------------------------------------------------------------
bash(10103)和它创建的子进程们(10606,10610,10611,10612)属于同一个会话期
sid为bash的进程号,所以bash为创建该会话的首进程
bash为一个进程组 10103
bash创建的php进程为一个进程组
这两个进程组同属一个会话期
程序daemon.php运行时创建了进程组10609,它即为组长
执行了daemon()
输出
10563
[root@hkui ~]# pstree -p|grep php
|-php(10564)-+-php(10565)
| |-php(10566)
| `-php(10567)
[root@hkui ~]# ps --sid 10564 -o pid,ppid,pgid,sid
PID PPID PGID SID
10564 1 10564 10564
10565 10564 10564 10564
10566 10564 10564 10564
10567 10564 10564 10564
执行了daemon.php后,程序运行起来了,进程id为10563
在10563里fork一次,得到子进程10564,父进程10563退出
子进程10564里执行setsid后发生了主要的以下三件事
1.10564创建了新的进程组,自己升级为组长
2.10564创建了新的会话组,并成为该会话组的会话首进程
3.10564和控制终端失去联系
由于其父进程10563退出,它的父进程变为init进程
在10564里fork了3个子进程,继承了10564的组Id,会话Id
php守护进程创建和简要分析的更多相关文章
- Linux 守护进程创建原理及简易方法
1:什么是Linux下的守护进程 Linux daemon是运行于后台常驻内存的一种特殊进程,周期性的执行或者等待trigger执行某个任务,与用户交互断开,独立于控制终端.一个守护进程的父进程是in ...
- Linux 守护进程创建
1. 守护进程: 是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.守护进程常常在系统启动时开始运行,在系统关闭时终止 2. ...
- Windows进程创建的流程分析
. 创建进程的大体流程: 创建进程的过程就是构建一个环境,这个环境包含了很多的机制 (比如自我保护, 与外界通信等等). 构建这个环境需要两种"人"来协调完成(用户态和内核 ...
- linux 守护进程创建流程
#include <sys/stat.h> #include <fcntl.h> /* Bit-mask values for 'flags' argument of beco ...
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- Linux之守护进程
一.守护进程概述 在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进 程.为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一 ...
- UNIX环境高级编程——守护进程
一.守护进程简介 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系 ...
- Linux 下Qt实现守护进程实例(转)
原文地址:Linux守护进程的编程方法(含实例) 作者:lingdxuyan 参考文献 Linux信号列表(zz) Linux 守护进程的编程方法 linux上编写守护进程的例程 Linux下后台守 ...
- linux守护进程编写实践
主要参考:http://colding.bokee.com/5277082.html (实例程序是参考这的) http://wbwk2005.blog.51cto.com/2215231/400260 ...
随机推荐
- 构建C 程序
1, 单个文件的编排顺序 #include指令 #define指令 类型定义 外部变量的声明 除main函数之外的函数的原型 main函数的定义 其他函数的定义
- Python数据挖掘之随机森林
主要是使用随机森林将four列缺失的数据补齐. # fit到RandomForestRegressor之中,n_estimators代表随机森林中的决策树数量 #n_jobs这个参数告诉引擎有多少处理 ...
- CentOS 7 下安装 MySQL 5.7
从 CentOS 7 系统开始,MariaDB 成为 yum 源中默认的数据库安装包.在 CentOS 7 及以上的系统中使用 yum 安装 MySQL 包将无法使用 MySQL.您可以选择使用完全兼 ...
- ESP32 - GPIO中断触发与事件回调
最近为项目增加了GPIO外部触发中断功能,原理是为GPIO32注册了上升沿触发事件,事件触发后,会向RTOS队列写入数据.在RTOS事件中检测到该队列中有新加入的事件,就读出,并执行相应代码. #de ...
- 2019年6月12日——开始记录并分享学习心得——Python3.7中对列表进行排序
Python中对列表的排序按照是排序是否可以恢复分为:永久性排序和临时排序. Python中对列表的排序可以按照使用函数的不同可以分为:sort( ), sorted( ), reverse( ). ...
- 机器学习SVD笔记
机器学习中SVD总结 矩阵分解的方法 特征值分解. PCA(Principal Component Analysis)分解,作用:降维.压缩. SVD(Singular Value Decomposi ...
- Luogu5280 [ZJOI2019] 线段树 【线段树】
题目分析: 这题除了分类讨论就没啥了... 容易发现问题实际就是所有操作选和不选按顺序执行的所有答案和.考虑每个点在多少种情况下会有tag. 那么,考虑新插入一个[l,r],所有有交集的点都会被清空, ...
- JAVA实现种子填充算法
种子填充算法原理在网上很多地方都能找到,这篇是继上篇扫描线算法后另一种填充算法,直接上实现代码啦0.0 我的实现只是实现了种子填充算法,但是运行效率不快,如果大佬有改进方法,欢迎和我交流,谢谢! 最后 ...
- 微信小程序通讯录字母排序
微信小程序通讯录 字母排序效果: demo地址:https://github.com/PeachCoder/wechat-contacts
- Go context 介绍和使用
context 上下文管理 context 翻译过来就是上下文管理,主要作用有两个: 控制 goroutine 的超时 保存上下文数据 WithTimeout 通过下面的一个简单的 http 例子进行 ...