0

0

PHP实现系统编程之 编写守护进程详解

不言

不言

发布时间:2018-04-13 10:48:05

|

1590人浏览过

|

来源于php中文网

原创

本篇文章给大家分享的内容是PHP实现系统编程之 编写守护进程详解,有着一定的参考价值,有需要的朋友可以参考一下

(一)进程组、会话、控制终端、控制进程等概念

进程组:每个进程都有一个所属的进程组 (process group),进程组有一个进程组长(process group leader),进程组ID即为这个进程组长的进程号,所以判断一个进程是否为进程组组长,只需比较该进称号是否和它的进程组id相等即可,PHP中可以用函数 posix_getpgrp() 获取当前进程的进程组id,用 posix_getpid() 获取当前进程的进程号。

 0) {
    sleep(2);
    echo '父进程:' . PHP_EOL;
}

echo "当前进程组gid:" . posix_getpgrp() . PHP_EOL;
echo "当前进程号pid:" . posix_getpid() . PHP_EOL;

if (isGroupLeader()) {
    echo 'Is a process group leader' . PHP_EOL;
}
else {
    echo 'Is not a process group leader' . PHP_EOL;
}

以上例程会输出:

立即学习PHP免费学习笔记(深入)”;

子进程:
当前进程组gid:15827
当前进程号pid:15828
Is not a process group leader
父进程:
当前进程组gid:15827
当前进程号pid:15827
Is a process group leader

会话:会话(session)是若干进程组的集合,会话中的一个进程组为会话组长(session leader),会话ID即为这个会话组长的进程组id,PHP中可以使用函数 posix_getsid(int $pid)  来获取指定进程的会话id,也可以使用函数 posix_setsid() 来创建一个新的会话,此时该进程成为新会话的会话组长,该函数调用成功返回新创建的会话ID,或者在失败出错时返回-1,注意linux中调用 posix_setsid() 函数的进程不能是进程组长,否则会调用失败,这是由于一个进程组中的进程不能同时跨多个会话

linux 中关于setsid的文档介绍:

setsid()  creates  a  new  session  if  the calling process is not a process group leader.  The calling process is the leader of the new session, the process group
       leader of the new process group, and has no controlling tty.  The process group ID and session ID of the calling process are set to the PID of the calling process.
       The calling process will be the only process in this new process group and in this new session.

以上例程会输出:

立即学习PHP免费学习笔记(深入)”;

当前会话id: 13000
当前进程是进程组长
int(-1)

那该如何新建会话呢,我们注意到前面使用pcntl_fork() 创建了一个子进程后,这个子进程就不是进程组长,所以可以利用子进程来创建新会话。

 0) {
    exit(0); // 让父进程退出
}
elseif ($pid == 0) {
    if (isGroupLeader()) {
        echo "是进程组组长\n";
    } else {
        echo "不是进程组组长\n";
    }
    echo "进程组ID:" . posix_getpgrp() . PHP_EOL;  
    echo "进程号pid: " . posix_getpid() . PHP_EOL;

    $ret = posix_setsid();
    var_dump($ret);

    echo "当前进程所属会话ID:" . posix_getsid(0) . PHP_EOL;
}

以上例程会输出:

立即学习PHP免费学习笔记(深入)”;

当前进程所属会话ID:13000
[root@localhost php]# 不是进程组组长
进程组ID:15856
进程号pid: 15857
int(15857)
当前进程所属会话ID:15857

利用子进程成功创建了新的会话。

控制终端控制进程:(终端是所有输入输出设备的总称,比如键盘,鼠标,显示器都是一个终端)一个会话可以有一个控制终端,一个控制终端被一个会话独占。会话刚创建的时候是没有控制终端的,但会话组长可以申请打开一个终端,如果这个终端不是其他会话的控制终端,这时的终端将会成为会话的控制终端,会话组长叫做控制进程。

linux下判断一个会话是否拥有控制终端,我们可以尝试打开一个特殊的文件 /dev/tty , 他指向了真实的控制终端,如果打开成功说明拥有控制终端,反之则没有控制终端。

 0) {
        sleep(1);
        $fp = fopen("/dev/tty", "rb");
        if ($fp) {
            echo "父进程会话 " . posix_getsid(0) . " 拥有控制终端\n";
        } else {
            echo "父进程会话 " . posix_getsid(0) . " 不拥有控制终端\n";
        }

    exit(0); // 让父进程退出
}
elseif ($pid == 0) {
    if (isGroupLeader()) {
        echo "是进程组组长\n";
    } else {
        echo "不是进程组组长\n";
    }

    $ret = posix_setsid();
    var_dump($ret);

    $fp = fopen("/dev/tty", "rb");
    if ($fp) {
            echo "子进程会话 " . posix_getsid(0) . " 拥有控制终端\n";
    }   else {
            echo "子进程会话 " . posix_getsid(0) . " 不拥有控制终端\n";
    }
}

上述例程子进程新建了一个会话,然后父子进程都尝试打开文件 /dev/tty,例程输出如下:

不是进程组组长
int(15906)
PHP Warning:  fopen(/dev/tty): failed to open stream: No such device or address in /root/php/setsid.php on line 30

Warning: fopen(/dev/tty): failed to open stream: No such device or address in /root/php/setsid.php on line 30
子进程会话 15906 不拥有控制终端
父进程会话 13000 拥有控制终端

产生SIGHUP信号

1、当一个会话失去控制终端时,内核会向该会话的控制进程发送一个 SIGHUP 信号,而通常会话的控制进程是shell进程,shell在收到一个 SIGHUP 信号时,会向由它创建的所有进程组(前台或后台进程组)也发送一个SIGHUP信号,然后退出,进程收到一个SIGHUP信号的默认处理方式就是退出进程,当然进程也可以自定义信号处理或者忽略它。

2、另外,当控制进程终止时,内核也会向终端的前台进程组的所有成员发送SIGHUP信号。

使用 php sighup.php运行起该程序,然后直接关掉终端,重新登录shell,会发现该程序仍在运行,daemon.txt 文件中会 记录捕获到的SIGHUP信号。

白月生产企业订单管理系统GBK2.0  Build 080807
白月生产企业订单管理系统GBK2.0 Build 080807

请注意以下说明:1、本程序允许任何人免费使用。2、本程序采用PHP+MYSQL架构编写。并且经过ZEND加密,所以运行环境需要有ZEND引擎支持。3、需要售后服务的,请与本作者联系,联系方式见下方。4、本程序还可以与您的网站想整合,可以实现用户在线服务功能,可以让客户管理自己的信息,可以查询自己的订单状况。以及返点信息等相关客户利益的信息。这个功能可提高客户的向心度。安装方法:1、解压本系统,放在

下载
[root@localhost php]# cat daemon.txt 
catch signal SIGHUP
[root@localhost php]# ps aux | grep sighup.php 
root     18438  0.0  0.4 191600  8996 ?        S    16:48   0:00 php sighup.php
root     18443  0.0  0.0 103328   896 pts/0    S+   16:53   0:00 grep sighup.php

同时linux下提供了一个nohup命令,可以让进程忽略所有的SIGHUP信号,例如

[root@localhost php]# nohup php sighup.php 
nohup: 忽略输入并把输出追加到"nohup.out"


(二)标准输入、标准输出、标准错误输出

php中有三个默认打开的文件句柄 STDIN,STDOUT, STDERR 分别对应上述三个文件描述符,而由于标准输入输出是和终端相关的,对于守护进程来说并没有什么用,可以直接关闭,但是直接关闭可能会造成一个问题,请看下面这段代码

运行上述代码时,屏幕不会输出echo的信息,而是写入到打开的文件中了,这是由于关闭STDOUT文件句柄后,释放了对应的文件描述符,而linux打开文件总是使用最小的可用文件描述符,所以这个文件描述符现在指向fopen打开的文件了,导致原本写到标准输出的信息现在写到了文件里。为了避免这种怪异的行为,我们在关闭这三个文件句柄之后可以立即打开 linux提供的黑洞文件 /dev/null,比如:

上面这个例程关闭STDIN,STDOUT, STDERR立马打开 /dev/null 三次,这样echo的信息会直接写到黑洞中,避免了前面出现的怪异的问题。


(三)编写守护进程涉及的其他问题

编写守护进程还涉及工作目录、文件掩码、信号处理、热更新、安全的启动停止等等问题,这里先留给大家自己百度,后期有空再来补充。

(四)一个守护进程的示例



to be continue!

相关推荐:

PHP实现系统编程之网络Socket及IO多路复用

PHP实现系统编程之本地套接字(Unix Domain Socket)

PHP实现系统编程之 多进程编程介绍及孤儿进程、僵尸进程




相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1965

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1291

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1198

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1400

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1229

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号