php守护进程创建和简要分析

守护进程可

  • 由系统启动脚本 /etc/rc.local
  • crontab任务,
  • 用户shell
    方式运行

具体概念可参考c的

进程守护化基本步骤

  • 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函数时
[[email protected] ~]# pstree -p|grep php
           |-sshd(3169)-+-sshd(10101)---bash(10103)---php(10609)-+-php(10610)
           |            |                                        |-php(10611)
           |            |                                        `-php(10612)

[[email protected] ~]# 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

[[email protected] ~]# ps --pid 10101 -o pid,ppid,pgid,sid
  PID  PPID  PGID   SID
10101  3169 10101 10101

[[email protected] ~]# 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

[[email protected] ~]# pstree -p|grep php
           |-php(10564)-+-php(10565)
           |            |-php(10566)
           |            `-php(10567)

[[email protected] ~]# 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

原文地址:https://www.cnblogs.com/HKUI/p/10848243.html

时间: 2024-08-30 14:02:11

php守护进程创建和简要分析的相关文章

Android --- Zygote和System进程启动过程简要分析

Android --- Zygote和System进程启动过程简要分析 在看过<Android情景源代码>的Zygote启动章节后,作如下简要总结.Zygote进程在init进程启动过程中被以service服务的形式启动: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root syste

对Minix3中进程模型的简要分析

简单介绍 Minix(Mini UNIX)原来是荷兰阿姆斯特丹的Vrije大学计算机科学系的Andrew S. Tanenbaum教授所发展的一个类Unix操作系统. 目前的Minix版本为Minix 3,是一个免费.开源的操作系统,设计目标是实现高可靠性.灵活性及安全性. 其系统主要包括在核心模式下运作的微核心和在用户模式下作为一系列独立.受保护的进程运行的其余所有操作系统组件. Minix3的整体认识 MINIX3本身就是一组进程的集合 第一层的主要功能是为上层驱动程序和服务器提供一组特权内

linux 守护进程创建流程

#include <sys/stat.h> #include <fcntl.h> /* Bit-mask values for 'flags' argument of becomeDaemon() */ #define BD_NO_CHDIR 01 /* Don't chdir("/") */ #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ #define BD_NO_REOPEN_ST

linux 创建守护进程的相关知识

linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关知识,需要的朋友可以参考下 关键字:linux.守护进程 创建子进程,父进程退出 这是编写守护进程的第一步.由于守护进程是脱离控制终端的,因此,完成第一步后就会在Shell终端里造成一程序已经运行完毕的假象.之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到

ASIO例子中的,守护进程初始化

// daemon.cpp // 该例子演示结合ASIO和POSIX标准系统的fork系统调用,产生一个守护进程. //时间服务器? // Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.t

nginx学习十三 初始fork和nginx守护进程ngx_daemon

学习nginx已经有一个多月了,觉得越来越吃力了,主要原因自己总结了一下:1平台是基于linux的,以前几乎没有接触过linux,而nginx使用了很多linux的函数:2就是进程,这个东西接触的也很少,linux的多进程更不用说,而现在正好看到这里,觉得异常的吃力,这不看到nginx守护进程的建立,就找资料好好学习一下,所以本文已学习fork为主要内容. 好了,先看一下nginx的守护进程的建立,然后在学习fork. http://blog.csdn.net/xiaoliangsky/arti

Linux 守护进程的原理与实现

一.守护进程概述 在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进 程.为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统. 守护进程是脱离于终端并且在后台运行的进程.守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端 信息所打断. 二.守护进程简介 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长 的进程,通

第十三章:守护进程

13.1:引言 守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,尽在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.Unixi有很多守护进程,它们执行日常事务活动. 13.2:守护进程的特征 查看守护进程: ps -axj 注意: 大多数守护进程都以超级用户特权运行.没有一个守护进程拥有控制终端,其终端名设置为问号(?),终端前台进程组ID设置为-1.内核守护进程以无控制终端方式启动.用户层守护进程缺少控制终端可能是守护进程调用了setsi

《网络编程》守护进程

前言 守护进程是在后台运行并独立于所有终端控制的进程.守护进程没有控制终端源于它们通常是由系统初始化脚本启动,但是也有可能从某个终端由用户在 shell 提示符下键入命令行启动,这种启动方式的守护进程必须亲自脱离与控制终端的关联,从而避免与作业控制.终端会话管理.终端产生信号等发生任何不期望的交互,也可以避免在后台运行的守护进程非预期地输出到终端.有关作业控制.终端控制的内容可参考文章<作业控制.终端控制 和 守护进程> 由于守护进程没有控制终端,当守护进程出错时,必须通过某种输出函数输出错误