显示标签为“Console”的博文。显示所有博文
显示标签为“Console”的博文。显示所有博文

2008年11月24日星期一

PHP 命令行 fork 多进程处理

很多人认为 PHP 没有多线程和多进程处理能力,其实 PHP 有多种运行模式。作为在作 web 应用的时候通常运行于 cgi 或者 web api 模块模式,web 服务器本身多进程或线程方式运行。而 PHP 在 cli 命令行模式下则有能力使用 fork 产生子进程(Windows 环境不可用)。本文将论述这种情况。

PHP 的进程控制支持实现了 Unix 类型的进程创建、程序执行、信号处理和进程终止。在 web 服务环境中不应该启用进程控制,如果在 web 服务环境中使用进程控制功能可能导致不可预料的结果。

int pcntl_fork(void)
fork 的意思是叉子,分岔路口。同样程序在这里分叉 ^_^。fork() 函数执行后,系统会将当前进程复制一份,子进程和父进程的差别只有 PID(进程号) 和 PPID(父进程号)不同。也就是说,这一点开始除了PID和PPID,子进程和父进程有同样的数据,也正在同样的控制流程中。所以注意一点,如果父进程在循环中fork(), 那么子进程也在循环中。
分叉点在这儿,fork()返回值:
  • 父进程从 fork() 得到的返回值是子进程的PID, 
  • 子进程从 fork() 得到的返回值是 0,
  • 如果父进程得到返回值是 -1 表示有错误发生,比如系统资源耗尽导致无法创建子进程。
因为创建的是进程,而每个进程的空间是相互独立的,所以在fork()这一刻子进程和父进程拥有相同的数据和状态,随后各自独立运行,改变的数据和状态不会相互影响。
$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}


[未完待续……]

2007年6月3日星期日

使用 Zend_Console_Getopt 处理 PHP 命令行

Linux 下写Shell只要在第一行加上
#!/path/to/php
然后将脚本加上执行属性即可 chmod +x

注意:Windows下编程再上传的朋友要注意。换行必须以linux格式,否则脚本会报错

require_once 'Zend/Console/Getopt.php';

定义规则:

使用短语
$opts = new Zend_Console_Getopt('abp:');

使用长语法
$opts = new Zend_Console_Getopt(
array(
'apple|a' => 'This option chooses apple, with no parameter',
'banana|b=i' => 'This option chooses banana, with required integer parameter',
'pear|p-s' => 'This option chooses pear, with optional string parameter'
)
);


捕获异常
try {
$opts = new Zend_Console_Getopt('abp:');
$opts->parse();
} catch (Zend_Console_Getopt_Exception $e) {
echo $e->getUsageMessage();
exit;
}


获取命令行选项和参数
$b = $opts->getOption('b');
$p = $opts->getOption('p');


另一种方法是使用 __get() and __isset() 魔术方法
if (isset($opts->b)) {
echo "I got the b option.\n";
}
$p = $opts->p; // null if not set