php进程后台调用(多线程/进程) php 多进程与多线程

php进程后台调用

http://blog.iyi.cn/start/2006/11/php_6.html

这两天在研究php模拟多线程的问题,碰到一个问题就是无论exec、popen、还是proc_open都会造成等待,也就是阻塞式的调用,而我想要得是无阻塞的调用,让程序在后台执行就可以解决问题,搜索之后找到了解决办法:

<?php/* Note that the call itself isn‘t sanitized in any way, so it‘simportant to make sure that this can‘t be exploited, seedocs for escapeshellcmd() for details*/// Demonstrationif(launchBackgroundProcess(‘touch testfile.txt‘)){print ‘Successfully launched background process‘;}/*** Launch Background Process** Launches a background process (note, provides no security itself, $call must be sanitized prior to use)* @param string $call the system call to make* @author raccettura*/function launchBackgroundProcess($call) {// Windowsif(is_windows()){pclose(popen(‘start /b ‘.$call.‘‘, ‘r‘));}// Some sort of UNIXelse {pclose(popen($call.‘ /dev/null &‘, ‘r‘));}return true;}/*** Is Windows** Tells if we are running on Windows Platform* @author raccettura*/function is_windows(){if(PHP_OS == ‘WINNT‘ || PHP_OS == ‘WIN32‘){return true;}return false;}?>

关键在于

‘ /dev/null &‘

(*nix下的后台运行方式)



‘start /b ‘

(windows下的后台运行方式)

想了一下,似乎很多脚本都可以用这种方式将一些操作移交后台进行,可以大幅提高效率。

如果要返回结果,则可以用异步执行并返回状态的方式,边处理边显示处理结果,这可以用在一些耗时较长的操作上,比如论坛备份恢复等:

<?php/***** Again notice this is unsanitized since we trust ourselves. Coming from the web* it would need to be sanitized to ensure it‘s safe to use. see escapeshellarg()****/$hostname = ‘accettura.com‘;?><!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><HTML xmlns="http://www.w3.org/1999/xhtml"><head><title>Traceroute to $hostname</title></head><body><?phpif(is_windows()){$cmd = ‘tracert -w 10‘;} else {$cmd = ‘traceroute -w 10‘;}$handle = popen("$cmd $hostname 2>&1", ‘r‘);while(!feof($handle)) {$buffer = fgets($handle);$buffer = ‘<p>‘.trim(htmlspecialchars($buffer)).‘</p>‘;echo $buffer;ob_flush();flush();}pclose($handle);/*** Is Windows** Tells if we are running on Windows Platform* @author raccettura*/function is_windows(){if(PHP_OS == ‘WINNT‘ || PHP_OS == ‘WIN32‘){return true;}return false;}?></body></html>继续php多线程/进程的问题

http://blog.iyi.cn/start/2006/11/php_6.html

昨天找到了进程后台运行的方法,今天测试了一下,发现popen的速度很慢,要40-50毫秒,exec更慢!类似的程序调用命令,都要经过系统调用,每次都开启一个php进程想必很慢。

比较笨的办法还是用fsockopen去通过http在server端get,试了一下,这样不会慢,缺点是增加了apache负载,每个请求都要在后台再请求一次。

我写了段脚本test.php,用fsockopen循环连接本地另外一个脚本test1.php,不做任何操作立即关闭连接,test1.php每次在文本文件test.cache中写入一行,循环100次的时候执行很快,test.cache中也正确的记录了100行。当循环1000次的时候,问题就来了,test.php执行了21.6888360977秒,也就是21秒内向apache发了1000个请求连test1.php,系统马上没有响应了,内存占用飙升到1G多,一分钟之后才恢复正常。test.cache中丢失63行,可能是由于apache超载造成的,但是系统内存却始终没有降下来,apache的占用了83M,剩下的不知道怎么回事- -

最后又找了半天,找到了fork实现的真正多线程!fork是pcntl(Process Control Functions)下的一个函数,pcntl只支持*nix系统,目前没有windows下的相关模块。(文档中说需要在编译php时--enable-pcntl,我用phpize编译成php模块的方式,通过在php.ini中添加extension=pcntl.so也可以使用。)

php手册里面就有了,但是在网上几乎找不到中文的文档!文档里面有这样一个实例:

<?phpdeclare(ticks=1);echo "I‘m going to be a Dad.n";if (spawn_child(‘child_function‘)) {echo ‘Parent pid:‘.posix_getpid()."n";}echo "I‘m going to be a Dad again!.n";if (spawn_child(‘child_function‘,1,2,3,4)) {echo ‘Child - 2 Parent pid:‘.posix_getpid()."n";}echo "What you‘re pregnant again!?.n";if (spawn_child(‘grand_children‘)) {echo ‘Child - 3 Parent pid:‘.posix_getpid()."n";}function grand_children() {echo "Dad I‘m going to have a baby.n";spawn_child(‘child_function‘,‘Joe‘);echo "I‘m so proud of my kids.n";}function spawn_child($function) {$original_pid = posix_getpid();$pid = pcntl_fork();if ($pid == -1) {die ("Unable to spawn childn");}$new_pid = posix_getpid();if ($new_pid == $original_pid) {return true;}if (function_exists($function)) {$numargs = func_num_args();if ($numargs > 1) {$args = func_get_args();//print_r ($args);unset($args[0]);call_user_func($function,$args);} else {call_user_func($function);}echo "Done with child ".$new_pid." they moved out.n";exit;} else {die ("$function does not existn");}}function child_function() {echo ‘Child pid:‘.posix_getpid()."n";$args = func_get_args();if (!empty($args))print_r ($args);}pcntl_wait( $status);?>

用pcntl实现的多线程可以解决很多问题了,但是似乎还是不能解决我的问题。在多线程虽然可以让程序并行执行,但所有的程序仍然在前台完成,在所有的线程完成之前,浏览器仍然会显示载入状态。在这种状态下,javascript代码不会执行,而我正是需要php产生一段javascript脚本,我想我的目的可能不是多线程或者并发处理,而是异步调用、后台执行,让生成脚本之外的操作在后台执行。

所以我的这种情况用最开始的fsockopen()方法可能更有效,但是fsockopen是不能进行异步处理的,如果要跟打开的连接进行交互,就没有任何优势可言了。不过我在网上找到了可以进行异步通信的办法,其实是变相的实现了多线程:php多路复用(多线程)[翻译]

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/52764.html

更多阅读

多进程与多线程区别 多线程 多进程的区别

网络编程中设计并发服务器,使用多进程与多线程 ,请问有什么区别?答案一:1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享

当代留守儿童问题的观察与思考 留守儿童的教育问题

宁化二中农村留守儿童产生的背景:在当代中国,当社会改革不断地推动着社会转型进程的同时,人们的社会生活和社会实践的方方面面,包括活动方式和交往方式以及认同方式都发生了剧烈的变化。我国的现代化进程与欧美发达国家有着不同的逻辑。

利率市场化与余额宝的兴起 余利宝和余额宝的区别

利率市场化与余额宝的兴起高善文姚学康尤宏业2014年3月24日内容提要本文第一部分介绍利率市场化改革进程与利率市场化现状,以贷款利率放开、存款利率管制为前提,构建利率市场化模型,作为对现实条件下中国银行体系运作的近似,分析存

乔姆斯基的生成语法 国外反思性语法教学

读《生成语法:标准理论到最简方案》(徐烈炯著)和《乔姆斯基的形式句法——历史进程与最新理论》(石定栩著)Chomsky的生成语法是当代语言学的精华,我对他的理论一直抱有敬畏。敬畏得不敢进入他那精密而富有变幻的世界。暑假趁暇,咬牙狠心

声明:《php进程后台调用(多线程/进程) php 多进程与多线程》为网友慢慢坚强分享!如侵犯到您的合法权益请联系我们删除