189 8069 5689

PHP如何实现守护进程

PHP 如何实现守护进程?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

10余年的湘东网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整湘东建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联从事“湘东网站设计”,“湘东网站推广”以来,每个客户项目都认真落实执行。

守护进程

守护进程作为一种常驻进程服务,很常见,例如 PHP-FPM, NGINX,redis,都需要一个父进程来支持整个服务。但是用 PHP 编写守护进程不多见,今天就来用 PHP 来实现一下。

步骤

● fork 子进程

● 父进程退出

● 设置新的会话

● 重置文件掩码

● 关闭标准输入输出

实现

我们对着以上的步骤来实现,在这之前需要 pcntl 和 posix 扩展,请确保安装了。

function daemon() {
    $pid = pcntl_fork();
    // fork 失败
    if ($pid < 0) {
        exit('fork failed');
    } else if ($pid > 0) {
       // 退出父进程
        exit(0);
    }
    // 设置新的会员
    // setsid 有几个注意点
    // 不能是进程组的组长调用
    // 对于进程组组员调用会产生新的会话和进程组,并成为该进程组的唯一成员,调用的进程将脱离终端
    if (posix_setsid() < 0) {
        exit('set sid failed');
    }
    // 重置文件掩码
    umask(0);
    // 切换工作目录
    chdir('/');
    // 关闭标准输入输出
    fclose(STDIN);
    fclose(STDOUT);
    fclose(STDERR);
}

细节

// 获取进程ID
var_dump(posix_getpid());
// 获取进程组ID
var_dump(posix_getpgid(posix_getpid()));
// 获取进程会话ID    
var_dump(posix_getsid(posix_getpid()));

三者结果相同,说明了该进程即使进程组的组长,也是会话首领。

为什么需要 umask (0)

当你在 linux 调用 umask 的时候你会看到一个掩码值,这个掩码决定了你创建文件权限范围,例如本人当前机器的 umask 为

0022

文件的最大权限是 0666,而目录的最大权限是 0777, 那么当前用户的创建的目录权限就是 0755,对于当前用户而言就是 rwx-rx-rx 权限。而文件则是 0644,对于当前用户而言 rw-r-r 权限。所以如果没有重置掩码的话,那么对于目录而言就是 0755,而文件则是 0644 了。

注意

如果你在进程使用了 echo var_dump 等函数,一定要把标准输出等重定向到其他文件流中。新增加下面代码就可以了。

global $stdin, $stdout, $stderr;
$stdin = fopen('/dev/null', 'r');
$stdout = fopen('/www/php/txt.txt','wb');
$stderr = fopen('/dev/null', 'wb');

因为在上面已经关闭了标准输入输出,此时文件描述符 fd 已经没有,所有重新打开之后 fd 从非负开始依次是 0,1,2。正好作为标准输入输出的文件。当然重定向到那里需要你自己设置。

最后的二次 fork

这个问题需要好好斟酌,因为是非必须的。目前想不到有什么场景下必须两次 Fork。

关于PHP 如何实现守护进程问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


网站栏目:PHP如何实现守护进程
网站路径:http://cdxtjz.cn/article/jdspod.html

其他资讯