|
|
用 PHP V5 开发多任务应用程序
来源:精英教育网综合 更新时间:2008-5-9 http://www.edu5a.com | | 精英教育阅读提示:许多 PHP 开发人员认为,由于标准的 PHP 缺少线程功能,因此实际 PHP 应用程序不可能执行多任务处理。例如,如果应用程序需要其他 Web 站点的信息,那么在远程检索完成之前它都必须停止。这是错误的!通过本文了解如何使用 stream_select 和 stream_socket_client 实现进程内 PHP 多任务处理。
|
|
清单 2. 从清单 1 中的程序获得的典型输出
Program starts at 02:38:50. Stream 4 closes at 02:38:53. Stream 3 closes at 02:38:56. Stream 2 closes at 02:38:59. Stream 1 closes at 02:39:02. Stream 0 closes at 02:39:05. | 了解这其中的工作原理至关重要。在较高层次上,第一个程序将发出几个 HTTP 请求并接收 Web 服务器发送给它的页面。虽然生产应用程序将很可能寻找若干个 Web 服务器的地址 —— 可能是 google.com、yahoo.com、ask.com 等 —— 但是此示例将把它的所有请求发送到位于 Phaseit.net 的企业服务器上,只为降低复杂度。
Web 页面请求在延迟(可变)后返回结果,如下所示。如果程序按顺序发出请求,则需花费大约 15+12+9+6+3 (45) 秒钟才能完成。如清单 2 所示,它实际上花费 15 秒钟完成。性能提高了三倍。
使这成为可能的是 PHP V5 的新 stream_select 函数。请求都是以常规方法发起,方法为打开几个 stream_socket_client 并向对应于 http://phaseit.net/demonstration/delay?delay=$DELAY 的每个 stream_socket_client 写入 GET。如果您通过浏览器请求此 URL,则在几秒钟之后,您将看到:
Starting at Thu Apr 12 15:05:01 UTC 2007. Stopping at Thu Apr 12 15:05:05 UTC 2007. 4 second delay. | 延迟服务器将作为 CGI 实现,如下所示:
清单 3. 延迟服务器实现
#!/bin/sh
echo "Content-type: text/html
<HTML> <HEAD></HEAD> <BODY>"
echo "Starting at `date`." RR=`echo $REQUEST_URI | sed -e 's/.*?//'` DELAY=`echo $RR | sed -e 's/delay=//'` sleep $DELAY echo "<br>Stopping at `date`." echo "<br>$DELAY second delay.</body></html>" | 虽然清单 3 的特殊实现特定于 UNIX?,但是本文中几乎所有实现都将很好地应用于 Windows?(尤其是 Windows 98 以后的版本)或 PHP 的 UNIX 安装。特别地,清单 1 可以托管在任意一个操作系统中。因此,Linux? 和 Mac OS X 都是 UNIX 变体,因此这里所有的代码都可以在两者的任意一种中运行。
按照以下顺序向延迟服务器发出请求。
清单 4. 进程启动顺序
delay=15 delay=12 delay= 9 delay= 6 delay= 3 | stream_select 的作用是尽可能快速地接收结果。在这种情况下,它执行的顺序与发出结果的顺序刚好相反。3 秒后,第一个页面已经准备好读取。程序的这一部分也符合常规 PHP —— 在本例中,使用 fread。就像在其他 PHP 程序一样,读取可以很好地通过 fgets 完成。
处理将以同样的方法继续。程序将在 stream_select 停止,直至数据就绪。重要的一点是,只要任何 连接具有数据,不管顺序怎样,程序都将开始读取。这是程序进行多任务处理或并发处理来自多个请求的结果的方法。
注意,这没有对主机 CPU 造成任何负担。经常会遇到这样一些连网程序,以 CPU 使用率急速上升至 100% 的方式在 while 中使用 fread。那种情况不会出现在这里,因为 stream_select 拥有支持立即响应所需的属性(只要有任何读取信息),但是它将在各读取操作间隙的等待时间内产生可忽略的 CPU 负载。
必备的 stream_select() 知识
诸如此类的基于事件的编程并不是最基本的。虽然清单 1 被简化到只包含最基本要素,但是涉及作为多任务应用程序必要元素的回调或协调的任何编码,比简单的程序顺序更让人觉得陌生。在这种情况下,大多数挑战集中在 $read 数组上。注意,它是一个引用;stream_select 将通过改变 $read 的内容返回重要信息。就像指针是 C 的最大绊脚石一样,引用似乎是 PHP 中最让程序员感到棘手的一部分。
您可以使用这项技术向任意个外部 Web 站点发出请求,确信您的程序会尽快收到所有结果,而无需等待其他请求。实际上,该技术将正确处理所有 TCP/IP 连接,而不只是 Web 端口 80 上的连接,因此您可以大体上管理 LDAP 检索、SMTP 传输、SOAP 请求等。 |
|
|
|
|
上一篇:用 PHP 构建自定义搜索引擎 下一篇:简单介绍 Session 的使用 |
|
| 相关新闻 |
|
|
|
|