从0到1优雅的实现PHP多进程管理
扫码关注公众号
原始发表:2018-06-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除
魁梧的小刀 · 【文章】瑞虎7 ...· 1 年前 · |
忐忑的眼镜 · 中华人民共和国政府和法兰西共和国政府关于相互 ...· 1 年前 · |
魁梧的咖啡豆 · 李小龙:我不怕练一万招的人,只怕把一招练一万 ...· 1 年前 · |
要出家的足球 · 绝美白莲花漫画下拉式第160话_黑莲花攻略手 ...· 1 年前 · |
帅气的勺子 · 中国地质大学(武汉)校长王焰新院士一行来我校 ...· 1 年前 · |
php 多进程 进程管理 |
https://cloud.tencent.com/developer/article/1734811?from=article.detail.1733608&areaSource=106000.15&traceId=NWIhsf2Zg3rwe3CFYDHef |
自信的可乐
1 年前 |
在我们实际的业务场景中(PHP技术栈),我们可能需要定时或者近乎实时的执行一些业务逻辑,简单的我们可以使用unix系统自带的crontab实现定时任务,但是对于一些实时性要求比较高的业务就不适用了,所以我们就需要一个常驻内存的任务管理工具,为了保证实时性,一方面我们让它一直执行任务(适当的睡眠,保证cpu不被100%占用),另一方面我们实现多进程保证并发的执行任务。
综上所述,我的目标就是:实现基于php-cli模式实现的master-worker多进程管理工具。其次,“我有这样一个目标,我是怎样一步步去分析、规划和实现的”,这是本文的宗旨。
备注:下文中,父进程统称为master,子进程统称为worker。
我们把这一个大目标拆成多个小目标去逐个实现,如下:
PHP fork进程的方法
pcntl_fork
, 这个大家应该有所了解,如果不知道的简单google/bing一下应该很容易找到这个函数。接着FTM, 我们看看
pcntl_fork
这个函数的使用方式大致如下:
接着看代码:
我们看到master有调用
pcntl_wait
或者
pcntl_waitpid
函数,为什么呢?首先我们在这里得提到两个概念,如下:
所以,
pcntl_wait
或者
pcntl_waitpid
的目的就是防止worker成为僵尸进程(zombie process)。
除此之外我们还需要把我们的master挂起和worker挂起,我使用的的是while循环,然后
usleep(200000)
防止CPU被100%占用。
最后我们通过下图(1-1)来简单的总结和描述这个多进程实现的过程:
上面实现了多进程和多进程的常驻内存,那master如何去管理worker呢?答案:多进程通信。话不多说google/bing一下,以下我列举几种方式:
所以我选择了“命名管道”的方式。我设计的通信流程大致如下:
接着还是逐个击破,当然话不多说还是google/bing一下。
posix_mkfifo
创建命名管道、
fopen
打开文件(管道以文件形式存在)、
fread
读取管道、
fclose
关闭管道就呼啸而出,哈哈,这样我们就能很容易的实现我们上面的思路的了。接着说说我在这里遇到的问题:
fopen
阻塞了,导致业务代码无法循环执行,一想不对啊,平常
fopen
普通文件不存在阻塞行为,这时候二话不说FTM搜
fopen
,crtl+f页面搜“block”,重点来了:
fopen() will block if the file to be opened is a fifo. This is true whether it's opened in "r" or "w" mode. (See man 7 fifo: this is the correct, default behaviour; although Linux supports non-blocking fopen() of a fifo, PHP doesn't).
翻译下,大概意思就是“当使用fopen的r或者w模式打开一个fifo的文件,就会一直阻塞;尽管linux支持非阻塞的打开fifo,但是php不支持。”,得不到解决方案,不支持,感觉要放弃,一想这种场景应该不会不支持吧,再去看看
posix_mkfifo
,结果喜出望外:
结论使用“r+”,同时我们又知道了使用
stream_set_blocking
防止紧接着的
fread
阻塞。接着我们用下图(1-2)来简单的总结和描述这个master-worker通信的方式。
最后我们需要解决的问题就是master怎么接受来自client的信号,google/bing结论:
如下图(1-3)所示,
接着我们只要实现不同信号下master&worker的策略,例如worker的重启等。这里需要注意的就是,当master接受到重启的信号后,worker不要立即exit,而是等到worker的业务逻辑执行完成了之后exit。具体的方式就是:
上面梳理完我们的实现方式后,接着我们就开始码代码了。码代码之前进行简单的建模,如下:
进程管理类Manager
进程抽象类Process
master实体类MasterProcess
worker实体类MasterProcess
最后我们需要做的就是优雅的填充我们的代码了。
项目地址 http://naruto.tigerb.cn/
个人知识还有很多不足,如果有写的不对的地方,希望大家及时指正。
THX~
扫码关注公众号
原始发表:2018-06-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除
帅气的勺子 · 中国地质大学(武汉)校长王焰新院士一行来我校座谈交流 1 年前 |
社区
活动
资源
关于
腾讯云开发者
扫码关注腾讯云开发者
领取腾讯云代金券
热门产品
热门推荐
更多推荐
Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287