PHP CLI模式下的多进程应用分析


Posted in PHP onJune 03, 2013

PHP在很多时候不适合做常驻的SHELL进程, 他没有专门的gc例程, 也没有有效的内存管理途径. 所以如果用PHP做常驻SHELL, 你会经常被内存耗尽导致abort而unhappy.

而且, 如果输入数据非法, 而脚本没有检测, 导致abort, 也会让你很不开心.

那? 怎么办呢?

多进程….

为什么呢?

优点:
1. 使用多进程, 子进程结束以后, 内核会负责回收资源
2. 使用多进程,子进程异常退出不会导致整个进程Thread退出. 父进程还有机会重建流程.
3. 一个常驻主进程, 只负责任务分发, 逻辑更清楚

Then, 怎么做呢?

接下来, 我们使用PHP提供的POSIX和Pcntl系列函数, 来实现一个PHP命令解析器, 主进程负责接受用户输入, 然后fork子进程执行, 并负责回显子进程的结束状态.

代码如下, 我加了注释, 如果有不懂的地方, 可以翻阅手册相关函数, 或者回复留言.

#!/bin/env php 
<?php 
/** A example denoted muti-process application in php 
* @filename fork.php 
* @touch date Wed 10 Jun 2009 10:25:51 PM CST 
* @author Laruence<laruence@baidu.com> 
* @license http://www.zend.com/license/3_0.txt PHP License 3.0 
* @version 1.0.0 
*/ /** 确保这个函数只能运行在SHELL中 */ 
if (substr(php_sapi_name(), 0, 3) !== 'cli') { 
die("This Programe can only be run in CLI mode"); 
} 
/** 关闭最大执行时间限制, 在CLI模式下, 这个语句其实不必要 */ 
set_time_limit(0); 
$pid = posix_getpid(); //取得主进程ID 
$user = posix_getlogin(); //取得用户名 
echo <<<EOD 
USAGE: [command | expression] 
input php code to execute by fork a new process 
input quit to exit 
Shell Executor version 1.0.0 by laruence 
EOD; 
while (true) { 
$prompt = "\n{$user}$ "; 
$input = readline($prompt); 
readline_add_history($input); 
if ($input == 'quit') { 
break; 
} 
process_execute($input . ';'); 
} 
exit(0); 
function process_execute($input) { 
$pid = pcntl_fork(); //创建子进程 
if ($pid == 0) {//子进程 
$pid = posix_getpid(); 
echo "* Process {$pid} was created, and Executed:\n\n"; 
eval($input); //解析命令 
exit; 
} else {//主进程 
$pid = pcntl_wait($status, WUNTRACED); //取得子进程结束状态 
if (pcntl_wifexited($status)) { 
echo "\n\n* Sub process: {$pid} exited with {$status}"; 
} 
} 
}

但有一点, 我一定要提醒:
Process Control should not be enabled within a webserver environment and unexpected results may happen if any Process Control functions are used within a webserver environment. --摘自PHP手也就是说, 打消你在PHP Web开发中使用多进程的念头吧!

原文:http://www.laruence.com/2009/06/11/930.html

PHP 相关文章推荐
用PHP和ACCESS写聊天室(二)
Oct 09 PHP
php获得文件扩展名三法
Nov 25 PHP
Zend Guard一些常见问题解答
Sep 11 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
Nov 24 PHP
解析wamp5下虚拟机配置文档
Jun 27 PHP
php中time()和mktime()方法的区别
Sep 28 PHP
php防止sql注入示例分析和几种常见攻击正则表达式
Jan 12 PHP
图文介绍PHP添加Redis模块及连接
Jul 28 PHP
yii2使用ajax返回json的实现方法
May 14 PHP
php gd等比例缩放压缩图片函数
Jun 12 PHP
Thinkphp实现站点静态化的方法详解
Mar 21 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
Feb 08 PHP
基于php-fpm 参数的深入理解
Jun 03 #PHP
php-cli简介(不会Shell语言一样用Shell)
Jun 03 #PHP
基于在生产环境中使用php性能测试工具xhprof的详解
Jun 03 #PHP
php cli模式学习(PHP命令行模式)
Jun 03 #PHP
获取PHP警告错误信息的解决方法
Jun 03 #PHP
php cli 小技巧
Jun 03 #PHP
php中用加号与用array_merge合并数组的区别深入分析
Jun 03 #PHP
You might like
短波问题解答
2021/02/28 无线电
中国广播史趣谈 — 几个历史第一次
2021/03/01 无线电
php正则校验用户名介绍
2008/07/19 PHP
CentOS6.5 编译安装lnmp环境
2014/12/21 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
PHP基于递归实现的约瑟夫环算法示例
2017/08/27 PHP
thinkphp5 migrate数据库迁移工具
2018/02/20 PHP
javascript cookies操作集合
2010/04/12 Javascript
JavaScript跨域方法汇总
2014/10/16 Javascript
javascript实现切换td中的值
2014/12/05 Javascript
node.js操作mongodb学习小结
2015/04/25 Javascript
js倒计时抢购实例
2015/12/20 Javascript
js正则表达式replace替换变量方法
2016/05/21 Javascript
json数据处理及数据绑定
2017/01/25 Javascript
浅谈React Native 中组件的生命周期
2017/09/08 Javascript
BootStrap TreeView使用实例详解
2017/11/01 Javascript
VUE脚手架的下载和配置步骤详解
2019/04/01 Javascript
微信小程序云开发之使用云函数
2019/05/17 Javascript
npm qs模块使用详解
2020/02/07 Javascript
js抽奖转盘实现方法分析
2020/05/16 Javascript
[01:16:16]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第二场 1月8日
2021/03/11 DOTA
简单讲解Python中的数字类型及基本的数学计算
2016/03/11 Python
bat和python批量重命名文件的实现代码
2016/05/19 Python
对python字典元素的添加与修改方法详解
2018/07/06 Python
Python封装原理与实现方法详解
2018/08/28 Python
python可迭代对象去重实例
2020/05/15 Python
英国顶级水晶珠宝零售商之一:Tresor Paris
2019/04/27 全球购物
药剂学专业应届生自荐信
2013/09/29 职场文书
2014年小学生教师节演讲稿范文
2014/09/10 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
班子个人四风问题整改措施
2014/10/04 职场文书
出差报告格式模板
2014/11/06 职场文书
2014年大学班长工作总结
2014/11/14 职场文书
先进党员事迹材料
2014/12/24 职场文书
新闻简讯格式及范文
2015/07/22 职场文书
MySQL脏读,幻读和不可重复读
2022/05/11 MySQL