大家都知道php调用系统命令常用的主要有以下几种方法:
如exec
(), system(),
passthru
(), shell_exec()
这几个函数的用法在此不做说明,有需要的请查阅php相关手册。
今天主要说的是:非阻塞的方式执行系统命令。
那么,首先什么是非阻塞呢?
要说非阻塞,我们先说一下什么是阻塞,下面先看一个例子:
a.php <? echo "begin:<br>"; echo exec('php b.php'); //我这里为了方便测试是拿php直接执行一个程序当做系统命令,你可以执行其他命令,比如一个shell脚本,或者系统的一些其他程序,如打包tar -cvf xxx。 echo "end"; ?> b.php <? $file = fopen("a.txt", "a+"); for($i=0;$i<100;$i++){ fwrite($file,"line".$i." Hello World. Testing! "); sleep(1); } fclose($file); echo "ok<br>"; ?>
我们在浏览器中访问上面的a.php后,发现浏览器一直转啊转,一直过了大概100秒才输出最后的结果,结果是:
begin
ok
end
结果说明a.php在执行exec()函数的时候一直在等待b.php执行完才返回,这就是阻塞。
我们在实际项目中,如果用户请求一个非常耗时的任务,比如耗时的批处理任务、文件打包或者大文件压缩等等,这时候如果采用阻塞方式,那么用户就需要在浏览器一直等,直到任务执行完返回才能干别的事。这很明显不是一个好的设计。那么有没有办法做到非阻塞,即,不用等待耗时任务执行完就返回,而且返回结果后后台还得把活干完?
答案是有的,请看下面对a.php的修改
<? echo "begin:<br>"; echo exec('php b.php'.' > /dev/null &'); echo "end"; ?>
没错照上面那样修改后,就可以了,那
> /dev/null & 是什么意思呢?
> 这个符号,熟悉命令行的都应该清楚是指输出
/div/null 这个在linux上是指空设备,是一个特殊的设备文件,我们可以认为是将输出信息丢弃。
& 这个符号,熟悉命令行的应该也清楚,是指后台执行
没错照上面那样修改完后,就可以实现php非阻塞方式的调用系统命令了。