快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

浅析php中实现多线程~

PHP中实现多线程? 看到这个标题, 你一定以为我疯了..但是事实上我真的这么做了.

下面是我的一些做法, 已经实验过. 确实可以的.

我们知道PHP本身是不支持多线程的, 但是我们的WEB服务器是支持多线程的.

也就是说可以同时让多人一起访问. 这也是我在PHP中实现多线程的基础.

假设我们现在运行的是a.php这个文件. 但是我在程序中又哀求WEB服务器运行另一个b.php

那么这两个文件将是同时执行的.

(PS: 一个链接哀求发送之后, WEB服务器就会执行它, 而不管客户端是否已经退出)

有些时候, 我们想运行的不是另一个文件, 而是本文件中的一部分代码.该怎么办呢?

其实可是通过参数来控制a.php来运行哪一段程序.

下面看一个例子:

//a.php

PHP代码:--------------------------------------------------------------------------------

<?php
function runThread()
{
$fp = fsockopen(\\'localhost\\', 80, $errno, $errmsg);

fputs($fp, "GET /a.php?act=b/r/n/r/n"); //这里的第二个参数是HTTP协议中规定的哀求头
//不明白的请看RFC中的定义

fclose($fp);
}

function a()
{
$fp = fopen(\\'result_a.log\\', \\'w\\');
fputs($fp, \\'Set in \\' . Date(\\'h:i:s\\', time()) . (double)microtime() . "/r/n");

fclose($fp);
}

function b()
{
$fp = fopen(\\'result_b.log\\', \\'w\\');
fputs($fp, \\'Set in \\' . Date(\\'h:i:s\\', time()) . (double)microtime() . "/r/n");

fclose($fp);
}

if(!isset($_GET[\\'act\\'])) $_GET[\\'act\\'] = \\'a\\';

if($_GET[\\'act\\'] == \\'a\\')
{
runThread();
a();
}
else if($_GET[\\'act\\'] == \\'b\\') b();
?>

--------------------------------------------------------------------------------


打开result_a.log 和 result_b.log 比较一下两个文件的中访问的时间. 大家会发现, 这两个的确是在不同线程中运行的.
有些时间完全相同.

上面只是一个简朴的例子, 大家可以改进成其它形式.


既然PHP中也能多线程了, 那么问题也来了, 那就是同步的问题. 我们知道 PHP本身是不支持多线程的. 所以更不会有什么像

Java 中synchronize的方式了. 那我们该如何做呢.

1. 尽量不访问同一个资源. 以避免冲突. 但是可以同时像数据库操作. 因为数据库是支持并发操作的. 所以在多线程的PHP中

不要向同一个文件中写入数据. 假如必须要写的话, 用别的方式进行同步.. 如调用 flock对文件进行加锁等. 或建立临时文件

并在另外的线程中等待这个文件的消失 while(file_exits(\\'xxx\\')); 这样就等于这个临时文件存在时, 表示其实线程正在操作

假如没有了这个文件, 说明其它线程已经释放了这个.

2. 尽量不要从runThread在执行fputs后取这个socket中读取数据. 因为要实现多线程, 需要的用非阻塞模式. 即在像fgets这

样的函数时立刻返回.. 所以读写数据就会出问题. 假如使用阻塞模式的话, 程序就不算是多线程了. 他要等上面的返回才执行

下面的程序. 所以假如需要交换数据最后利用外面文件或数据中完成. 实在想要的话就用socket_set_nonblock($fp) 来实现.


说了这么多, 倒底这个有没有实际的意义呢? 在什么时候需要这种用这种方式呢 ?

答案是肯定的. 大家知道. 在一个不断读取网络资源的应用中, 网络的速度是瓶颈. 假如采多这种形式就可以同时以多个线程对

不同的页面进行读取.

本人做的一个能从8848、soaso这些商城网站搜索信息的程序。还有一个从阿里巴巴网站上读取商业信息和公司目录的程序也用到

了此技术。 因为这两个程序都是要不断的链接它们的服务器读取信息并保存到数据库。 利用此技术正好消除了在等待响应时的瓶

颈。


仅以此抛砖引玉, 希望大家多来讨论~~~~~~~






返回类别: 教程
上一教程: PHP新手上路(十四)
下一教程: 第三节 定义一个类 [3]

您可以阅读与"浅析php中实现多线程~"相关的教程:
· 浅析PHP中实现多线程
· PHP4中实现动态代理
· PHP中实现面向对象编程
· PHP中实现大图自动缩成小图(及GD库的安装)
· 在PHP3中实现SESSION的功能(一、SESSION函数库:session.inc.php3)(转译)
    微笑服务 优质保证 索取样品