如何实现phpphp 多线程 异步处理理

您还可以使用以下方式登录
当前位置:&>&&>&&>& > 实现PHP多线程异步请求的3种方法
实现PHP多线程异步请求的3种方法
&实现PHP多线程异步请求的方法有很多,在本文整理了3种不多的常用方法,大家可以参考下在网上看过很多版本的PHP异步请求方法,这里简单总结几个常用方法分享给大家&&1、用CURL实现一步请求&&CURL扩展是我们在开发过程中最常用的一种方法,他是一个强大的HTTP命令行工具,可以模拟POST/GET等HTTP请求,然后得到和提取数据,显示在&标准输出&(stdout)上面。&&示例:&&代码如下:&?php&$cl = curl_init();&$curl_opt = array(CURLOPT_URL, '/demo.php',&CURLOPT_RETURNTRANSFER, 1,&CURLOPT_TIMEOUT, 1,);&curl_setopt_array($cl, $curl_opt);&curl_exec($ch);&curl_close($ch);&?&&&由于CUROPT_TIMEOUT属性最小值为1,这就意味着在客户端必须等待1秒,这也是使用CURL方法的缺点&&2、用popen()函数实现异步请求&&语法格式:popen(command,mode)&&示例:&&代码如下:&?php&$file = popen(&/bin/ls&,&r&);&//这里是要执行的代码&//...&pclose($file);&?&&&popen()函数直接打开一个指向进程的管道,速度快,即时相应。但是这个函数是单项的,要么读要么写,而且如果并发数较大,则会产生大量进程,给服务器造成负担。&&另外,如同示例中一样,程序结束后一定要用pclose()来关闭。&&3、用fscokopen()函数实现异步请求&&我们在平时开发邮件发送功能等socket编程时,都会用到这个函数,在使用这个函数之前,我们要在PHP.ini 中开启 allow_url_fopen 选项,另外在变成时,我们还要自己手动拼接出header部分。&&示例:&&代码如下:$fp = fsockopen(&/demo.php&, 80, $errno, $errstr, 30);&if (!$fp) {&echo &$errstr ($errno)&br /&n&;&} else {&$out = &GET /index.php / HTTP/1.1rn&;&$out .= &Host: rn&;&$out .= &Connection: Closernrn&;&&fwrite($fp, $out);&/*这里忽略执行结果&*测试时可以打开&while (!feof($fp)) {&echo fgets($fp, 128);&}*/&fclose($fp);&}&&PHP本身没有多线程,但是我们可以用其他方式来实现多线程的效果,上面列举的三种方式都有各自的优缺点,大家在使用时可以根据程序的需要择优选择。&&UncleToo经验尚浅,这里就简单总结了这么多,如果有其他更好的实现PHP多线程的方法可以一起讨论!&&
欢迎转载:
推荐:    & PHP实现真正的异步MySQL
PHP实现真正的异步MySQL
node.js之类的语言可以实现异步的数据库查询功能,执行SQL语句之后不必等待数据库返回结果。继续去执行其他的代码,当数据库返回结果是再对数据进行处理,如渲染页面,并将HTML页面发送给客户端。这样应用程序完全不需要阻塞等待。这种方式运行效率非常高。
PHP中是否可以实现类似的异步非阻塞MySQL查询呢?使用github搜索发现一个项目貌似是做此功能的,,查看代码是基于.的。但并不是真正的异步SQL。实现的原理是设置一个定时器,每0.02秒轮询一次。虽然也可以用,但这样很浪费CPU资源。不是真正的异步MYSQL。
现在Swoole1.6.2提供了swoole_event_add和swoole_get_mysqli_sock 2个新的函数,使用它完全可以实现真正的PHP异步MySQL。下面讲一下具体的实现。
$db-&connect('127.0.0.1', 'root', 'root', 'test');
$db-&query("show tables", MYSQLI_ASYNC);
swoole_event_add(swoole_get_mysqli_sock($db), function($db_sock) {
$res = $db-&reap_async_query();
var_dump($res-&fetch_all(MYSQLI_ASSOC));
swoole_event_exit();
首先连接mysql,连接成功后执行SQL语句,要在第二个参数指定MYSQLI_ASYNC。表示此查询为异步。query函数会立即返回,这时候并没有得到mysqli_result。
然后调用swoole_get_mysqli_sock函数取到mysql连接的socket,并调用swoole_event_add将它加入到swoole的epoll事件循环中。当数据库返回结果是会回调我们刚才制定的函数。
这时候再调用mysqli_reap_async_query得到result,调用fetch_all函数得到数据。
这个过程是完全异步非阻塞的,不存在任何浪费CPU的代码。这个代码还可以用在服务器端程序上,具体代码实现后续会再写一篇文章详细介绍。实现异步处理,数据量较大,如何边处理边显示
php& ajax& 实现异步处理,数据量较大,等待时间较长。现在想提高效率,达到边处理的同时,显示结果,不会造成等待时间较长的状态
分批获取数据
--- 共有 1 条评论 ---
可能没懂我的意思,谢谢。我是希望ajax一次处理、多次实时显示
--- 共有 1 条评论 ---
可能没懂我的意思,谢谢。我是希望ajax一次处理、多次实时显示结果
用长连接 websocket
--- 共有 1 条评论 ---
哦,谢谢。
ob_end_flush(); ob_implicit_flush(1);
或改成后台处理,先成功,后执行(任务计划)私信发送成功
检测到您已登录开源中国,是否

PHP不等待返回异步调用的实现方法


PHP异步执行个人觉得还是用队列最好,这里可以查看下PHP定时执行计划任务 。
但如果硬件不容许的话就没办法了,这里介绍常用方式常见的有以下几种,可以根据各自优缺点进行选择:
1.客户端页面采用AJAX技术请求服务器
优点:最简单,也最快,就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。

缺点:一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。

而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。

当然,还可以使用其他的类似原理的方法,比如script标签等等。
2.popen()函数
该函数打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。

所以可以通过调用它,但忽略它的输出。使用代码如下:
pclose(popen("/home/xinchen/backend.php &", 'r'));

优点:避免了第一个方法的缺点,并且也很快。

缺点:这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。
3.CURL扩展
CURL是一个强大的HTTP命令行工具,可以模拟POST/GET等HTTP请求,然后得到和提取数据,显示在"标准输出"(stdout)上面。代码如下:
$ch = curl_init();
$curl_opt = array(CURLOPT_URL, ' CURLOPT_RETURNTRANSFER, 1, CURLOPT_TIMEOUT, 1,);
curl_setopt_array($ch, $curl_opt);
curl_exec($ch);
curl_close($ch);

缺点:如你问题中描述的一样,由于使用CURL需要设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。
4.fscokopen()函数
fsockopen支持socket编程,可以使用fsockopen实现邮件发送等socket程序等等,使用fcockopen需要自己手动拼接出header部分

可以参考: 

使用示例如下:
$fp = fsockopen("", 80, $errno, $errstr, 30);
if (!$fp) {

echo "$errstr ($errno)&br /&\n";
} else {

$out = "GET /index.php
/ HTTP/1.1\r\n";

$out .= "Host: \r\n";

$out .= "Connection: Close\r\n\r\n";

fwrite($fp, $out);

/*忽略执行结果

while (!feof($fp)) {

echo fgets($fp, 128);

}*/

fclose($fp);
}

所以总结来说,fscokopen()函数应该可以满足您的要求。可以尝试一下。

PHP 本身没有多线程的东西,但可以曲线的办法来造就出同样的效果,比如多进程的方式来达到异步调用,只限于命令模式。还有一种更简单的方式,可用于 Web 程序中,那就是用 fsockopen()、fputs() 来请求一个 URL 而无需等待返回,如果你在那个被请求的页面中做些事情就相当于异步了。

关键代码如下:
$fp=fsockopen('localhost',80,&$errno,&$errstr,5);
if(!$fp){

echo "$errstr ($errno)&br /&\n";
}
fputs($fp,"GET another_page.php?flag=1\r\n");
fclose($fp);

上面的代码向页面 another_page.php 发送完请求就不管了,用不着等待请求页面的响应数据,利用这一点就可以在被请求的页面 another_page.php 中异步的做些事情了。

比如,一个很切实的应用,某个 Blog 在每 Post 了一篇新日志后需要给所有它的订阅者发个邮件通知。如果按照通常的方式就是:


日志写完 -& 点提交按钮 -& 日志插入到数据库 -& 发送邮件通知 -&告知撰写者发布成功


那么作者在点提交按钮到看到成功提示之间可能会等待很常时间,基本是在等邮件发送的过程,比如连接邮件服务异常、或器缓慢或是订阅者太多。而实际上 是不管邮件发送成功与否,保证日志保存成功基本可接受的,所以等待邮件发送的过程是很不经济的,这个过程可异步来执行,并且邮件发送的结果不太关心或以日 志形式记录备查。

改进后的流程就是:


日志写完 -& 点提交按钮 -& 日志插入到数据库 ---&告知撰写者发布成功

└发送邮件通知 -& [记下日志]


用个实际的程序来测试一下,有两个 php,分别是 write.php 和 sendmail.php,在 sendmail.php 用 sleep(seconds) 来模拟程序执行使用时间。

write.php,执行耗时 1 秒
&?php 

function asyn_sendmail() {

$fp=fsockopen('localhost',80,&$errno,&$errstr,5);

if(!$fp){

echo "$errstr ($errno)&br /&\n";

sleep(1);

fputs($fp,"GET /sendmail.php?param=1\r\n"); #请求的资源 URL 一定要写对

fclose($fp);

} 

echo time().'&br&';

echo 'call asyn_sendmail&br&';

asyn_sendmail();

echo time().'&br&';
?&

sendmail.php,执行耗时 10 秒
&?php

//sendmail();

//sleep 10 seconds

sleep(10);

fopen('C:\'.time(),'w');
?&

通过页面访问 write.php,页面输出:
 call asyn_sendmail


并且在 C:\ 生成文件:


从上面的结果可知 sendmail.php 花费至少 10 秒,但不会阻塞到 write.php 的继续往下执行,表明这一过程是异步的。

本文来源:

你可以在后,对此项目发表评论2012年2月 PHP大版内专家分月排行榜第一2012年1月 PHP大版内专家分月排行榜第一2011年11月 PHP大版内专家分月排行榜第一2011年9月 PHP大版内专家分月排行榜第一
2012年3月 PHP大版内专家分月排行榜第二2011年12月 PHP大版内专家分月排行榜第二2011年10月 PHP大版内专家分月排行榜第二
2012年2月 PHP大版内专家分月排行榜第一2012年1月 PHP大版内专家分月排行榜第一2011年11月 PHP大版内专家分月排行榜第一2011年9月 PHP大版内专家分月排行榜第一
2012年3月 PHP大版内专家分月排行榜第二2011年12月 PHP大版内专家分月排行榜第二2011年10月 PHP大版内专家分月排行榜第二
2012年2月 PHP大版内专家分月排行榜第一2012年1月 PHP大版内专家分月排行榜第一2011年11月 PHP大版内专家分月排行榜第一2011年9月 PHP大版内专家分月排行榜第一
2012年3月 PHP大版内专家分月排行榜第二2011年12月 PHP大版内专家分月排行榜第二2011年10月 PHP大版内专家分月排行榜第二
2013年6月 Linux/Unix社区大版内专家分月排行榜第二2013年5月 Linux/Unix社区大版内专家分月排行榜第二2013年3月 Linux/Unix社区大版内专家分月排行榜第二2013年1月 Linux/Unix社区大版内专家分月排行榜第二2012年12月 Linux/Unix社区大版内专家分月排行榜第二2012年8月 Linux/Unix社区大版内专家分月排行榜第二2011年12月 Linux/Unix社区大版内专家分月排行榜第二2011年10月 C/C++大版内专家分月排行榜第二2011年10月 Linux/Unix社区大版内专家分月排行榜第二
2012年6月 C/C++大版内专家分月排行榜第三2012年6月 PHP大版内专家分月排行榜第三2012年5月 C/C++大版内专家分月排行榜第三2012年3月 Linux/Unix社区大版内专家分月排行榜第三2012年2月 Linux/Unix社区大版内专家分月排行榜第三2011年11月 C/C++大版内专家分月排行榜第三
2013年5月 总版技术专家分月排行榜第一
2016年7月 总版技术专家分月排行榜第二2016年3月 总版技术专家分月排行榜第二2015年12月 总版技术专家分月排行榜第二2014年8月 总版技术专家分月排行榜第二2014年7月 总版技术专家分月排行榜第二2013年6月 总版技术专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 php如何异步调用 的文章

 

随机推荐