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

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

那? 怎么办呢?

多进程….

为什么呢?

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

Then, 怎么做呢?

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

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

  1. #!/bin/env php
  2. <?php
  3. /** A example denoted muti-process application in php
  4. * @filename fork.php
  5. * @touch date Wed 10 Jun 2009 10:25:51 PM CST
  6. * @author Laruence<laruence@baidu.com>
  7. * @license http://www.zend.com/license/3_0.txt PHP License 3.0
  8. * @version 1.0.0
  9. */
  10. /** 确保这个函数只能运行在SHELL中 */
  11. if (substr(php_sapi_name(), 0, 3) !== 'cli') {
  12. die("This Programe can only be run in CLI mode");
  13. }
  14. /** 关闭最大执行时间限制, 在CLI模式下, 这个语句其实不必要 */
  15. set_time_limit(0);
  16. $pid = posix_getpid(); //取得主进程ID
  17. $user = posix_getlogin(); //取得用户名
  18. echo <<<EOD
  19. USAGE: [command | expression]
  20. input php code to execute by fork a new process
  21. input quit to exit
  22. Shell Executor version 1.0.0 by laruence
  23. EOD;
  24. while (true) {
  25. $prompt = "\n{$user}$ ";
  26. $input = readline($prompt);
  27. readline_add_history($input);
  28. if ($input == 'quit') {
  29. break;
  30. }
  31. process_execute($input . ';');
  32. }
  33. exit(0);
  34. function process_execute($input) {
  35. $pid = pcntl_fork(); //创建子进程
  36. if ($pid == 0) {//子进程
  37. $pid = posix_getpid();
  38. echo "* Process {$pid} was created, and Executed:\n\n";
  39. eval($input); //解析命令
  40. exit;
  41. } else {//主进程
  42. $pid = pcntl_wait($status, WUNTRACED); //取得子进程结束状态
  43. if (pcntl_wifexited($status)) {
  44. echo "\n\n* Sub process: {$pid} exited with {$status}";
  45. }
  46. }
  47. }

但有一点, 我一定要提醒:

  1. 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开发中使用多进程的念头吧!

PHP CLI模式下的多进程应用的更多相关文章

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

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

  2. php cli模式下获取参数的方法

    转载声明:http://blog.csdn.net/fdipzone/article/details/51945892 php在cli模式下接收参数有两种方法 1.使用argv数组 <?php ...

  3. php在cli模式下取得命令行中的参数的方法-getopt命令行可传递数组-简单自定义方法取命令行参数

    在cli模式下执行PHP时,自动给脚本文件传递了一个变量$argv,其值即是一个命令中所有值组成的数组(以空格区分),在PHP程序中接收参数有3种方法1.直接使用argv变量数组. 2.使用$_SER ...

  4. PHP CLI模式下echo换行

    近日在执行导库程序的时候,需要在CLI模式下运行程序进行调试,如下图,这是什么鬼?不是我想要的结果 后经过查资料发现代码中执行的输出为 //错误方法实例 echo '其他-683\n'; //正确打开 ...

  5. 解决 php7 cli 模式下中文乱码的两中方法

    解决 php7 cli 模式下中文乱码的两中方法1. 给PHP文件开头加上 exec('chcp 936'); 然后把该文件以 ANSI 格式编码2. 在 php.ini 中设置 default_ch ...

  6. php CLI 模式下的传参方法

    在CLI模式(命令行界面 Command Line Interface)下,传入参数有如下3种方法: 一. getopt函数(PHP 4 >= 4.3.0, PHP 5) getopt - 从命 ...

  7. Php cli模式下执行报错/usr/bin/php: /usr/local/lib/libxml2.so.2: no version information available (required by /usr/bin/php)

    centos下php cli模式报错 /usr/bin/php: /usr/local/lib/libxml2.so.2: no version information available (requ ...

  8. PHP在cli模式下传参说明

    命令行下输入php -help会列出所有可用的参数,如下截图: -a 代表以交互式模式运行: -c 指定ph.ini -n 不使用任何php.ini配置 -d foo[=bar] 定义一个INI实体, ...

  9. php cli 模式下执行文件,require 加载路径错误

    今天,同事突然告诉我,我写的一个做计划任务的php脚本执行总是不成功. 脚本本身很简单,里面只有包含了几个库文件并执行了一个函数,函数应该没有错误,这个函数在别处也调用过,没有问题.我在本地用浏览器访 ...

随机推荐

  1. 2018 ACM 网络选拔赛 北京赛区

    A Saving Tang Monk II #include <bits/stdc++.h> using namespace std; ; struct node { int x,y,z, ...

  2. Tarjan 模板,高级并查集

    第一个模板有误!!!! 请见谅!!! 要怪就怪HDU吧,竟然让我过了 第二个模板是正确的.请翻到下面看更新 HDU 1269 评论区居然有人说用并查集过了,其实回想一下 求无向图的连通分量,就是并查集 ...

  3. wkhtmltopdf 安装过程不包含php扩展部分

    Qt Webkit HTML Converter Install wkhtmltopdf This page documents installation of wkhtmltopdf on Gent ...

  4. ElasticSearch 例子

    ElasticSearch是一个接近实时的搜索平台,它利用Lucese进行文档索引. 本文会写个可以运行的简单例子,方便大家上手,日后深入了解. 需要引入maven依赖 <dependency& ...

  5. #define宏定义中## #@ # \ 符号使用

    C/C++ 宏命令的神奇用法. 先看下面三条语句: #define Conn(x,y)     x##y#define ToChar(x)     #@x#define ToString(x)    ...

  6. PHP7 学习笔记(九)phpsize动态编译openssl扩展 (微信公众平台)

    先吐槽,微信公众平台授权出问题了,尽然访问不了 一.问题描述: 使用PHP中的库函数file_get_contents时出现Unable to find the wrapper "https ...

  7. 完整版ffmpeg使用情况

    protected void Page_Load(object sender, EventArgs e) { string filePath = @"D:/Prjects/MT147/exa ...

  8. Error: Cannot find module PhantomJS

    node install.js Considering PhantomJS found at /usr/local/bin/phantomjs Looks like an `npm install - ...

  9. B. Planning The Expedition

    题目链接:http://codeforces.com/contest/1011/problem/B 题目大意: 输入的n,m代表n个人,m个包裹. 标准就是 每个人一开始只能选定吃哪一个包裹里的食物, ...

  10. Android判断当前是否在主线程

    Android开发中, 有时需要判断当前线程到底是主线程, 还是子线程, 例如: 我们在自定义View时, 想要让View重绘, 需要先判断当前线程到底是不是主线程, 然后根据判断结果来决定到底是调用 ...