β

PHP 并发执行命令之multi_cmd

PHPor 的Blog 97 阅读
PHP

代码功能:

同时执行多条命令,花费时间接近于最长那条命令的时间,而不是每条命令执行的时间和。

<?php

function multi_cmd($arr) {
	$arrResult = array();
	$arrFp = array();
	foreach($arr as  $k => $cmd) {
		$arrFp[$k] = popen($cmd, "r");
		if(!$arrFp[$k]) {
			$arrResult[$k] = null;
			unset($arrFp[$k]);
			continue;
		}
		stream_set_blocking($arrFp[$k], false);
	}
	$write = null;
	$expect = null;
	while(count($arrFp) > 0) {
		$arrRead = array_values($arrFp);
		$ret = stream_select($arrRead, $write, $expect, 0, 200000);
		if($ret === false) break;
		if($ret === 0) continue;
		foreach($arrFp as $k=>$fp) {
			while(!feof($fp)) {
				$r = fread($fp, 1024);
				if ($r === false) break;
				$arrResult[$k] .= $r;
				if (feof($fp)) unset($arrFp[$k]);
			}
		}
	}
	return $arrResult;
}
$arr = array(
	"cmd1" => "sleep 1; eacho 1",
	"cmd2" => "sleep 2; echo 2",
	"cmd3" => "sleep 3; echo 3",
);
$arrResult = multi_cmd($arr);
print_r($arrResult);

但凡用到该函数的,都是比较关心耗时的,所以,下面改进一下,加入耗时统计:

function multi_cmd($arr) {
	$arrResult = array();
	$arrFp = array();
	foreach($arr as  $k => $cmd) {
		$arrFp[$k] = popen($cmd, "r");
		if(!$arrFp[$k]) {
			$arrResult[$k] = array("stdout" => null, "meta"=>array("elapse"=>0));
			unset($arrFp[$k]);
			continue;
		}
		stream_set_blocking($arrFp[$k], false);
	}
	$start = microtime(1);
	$write = null;
	$expect = null;
	while(count($arrFp) > 0) {
		$arrRead = array_values($arrFp);
		$ret = stream_select($arrRead, $write, $expect, 0, 200000);
		if($ret === false) break;
		if($ret === 0) continue;
		foreach($arrFp as $k=>$fp) {
			while(!feof($fp)) {
				$r = fread($fp, 1024);
				if ($r === false) break;
				$arrResult[$k]["stdout"] .= $r;
				if (feof($fp)) {
					unset($arrFp[$k]);
					$arrResult[$k]["meta"]["elapse"] = microtime(1) - $start;
				}
			}
		}
	}
	return $arrResult;
}
$arrResult = multi_cmd($arr);
print_r($arrResult);
PHP
作者:PHPor 的Blog
PHP+Mysql+Apache+Linux
原文地址:PHP 并发执行命令之multi_cmd, 感谢原作者分享。

发表评论