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+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
Dec 16 PHP
PHPWind 发帖回帖Api PHP版打包下载
Feb 08 PHP
php+js实现异步图片上传实例分享
Jun 02 PHP
php写入数据到CSV文件的方法
Mar 14 PHP
php实现curl模拟ftp上传的方法
Jul 29 PHP
腾讯CMEM的PHP扩展编译安装方法
Sep 25 PHP
Yii中CGridView实现批量删除的方法
Dec 28 PHP
Yii 2.0如何使用页面缓存方法示例
May 23 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
Aug 21 PHP
Thinkphp自定义生成缩略图尺寸的方法
Aug 05 PHP
php7 图形用户界面GUI 开发示例
Feb 22 PHP
php中数组最简单的使用方法
Dec 27 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
PHP文件上传操作实例详解
2016/09/27 PHP
实现PHP搜索加分页
2016/10/12 PHP
php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例
2019/05/09 PHP
详解php反序列化
2020/06/10 PHP
Jquery动态改变图片IMG的src地址示例
2013/06/25 Javascript
表格奇偶行设置不同颜色的核心JS代码
2013/12/24 Javascript
js中this的用法实例分析
2015/01/10 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
JS中微信小程序自定义底部弹出框
2016/12/22 Javascript
javascript history对象详解
2017/02/09 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
React Native 自定义下拉刷新上拉加载的列表的示例
2018/03/01 Javascript
在Mac下彻底卸载node和npm的方法
2018/05/16 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
JavaScript实现英语单词题库
2019/12/24 Javascript
js实现页面图片消除效果
2020/03/24 Javascript
JavaScript实现页面高亮操作提示和蒙板
2021/01/04 Javascript
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
[04:56]经典回顾:前Ehome 与 前LGD
2015/02/26 DOTA
Python中import机制详解
2017/11/14 Python
python使用jieba实现中文分词去停用词方法示例
2018/03/11 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
Python 字符串与数字输出方法
2018/07/16 Python
Django框架模板文件使用及模板文件加载顺序分析
2019/05/23 Python
Java byte数组操纵方式代码实例解析
2020/07/22 Python
Bogner美国官网:滑雪服中的”Dior”
2018/01/30 全球购物
新西兰最大的天然保健及护肤品网站:HealthPost(直邮中国)
2021/02/13 全球购物
如何在发生故障的节点上重新安装 SQL Server
2013/03/14 面试题
秋季运动会通讯稿
2014/01/24 职场文书
八年级数学教学反思
2014/01/31 职场文书
超市商业计划书
2014/05/04 职场文书
理想点亮人生演讲稿
2014/05/21 职场文书
2014年班干部工作总结
2014/11/25 职场文书
2016感恩父亲节主题广播稿
2015/12/18 职场文书
MySQL 8.0 之不可见列的基本操作
2021/05/20 MySQL