好像可以,以前看过这样的文章
不过没试过============================================PHP中实现多线程? 看到这个标题, 你一定以为我疯了..但是事实上我真的这么做了.下面是我的一些做法, 已经实验过. 确实可以的.我们知道PHP本身是不支持多线程的, 但是我们的WEB服务器是支持多线程的.也就是说可以同时让多人一起访问. 这也是我在PHP中实现多线程的基础.假设我们现在运行的是a.php这个文件. 但是我在程序中又请求WEB服务器运行另一个b.php那么这两个文件将是同时执行的. (PS: 一个链接请求发送之后, WEB服务器就会执行它, 而不管客户端是否已经退出)有些时候, 我们想运行的不是另一个文件, 而是本文件中的一部分代码.该怎么办呢?其实可是通过参数来控制a.php来运行哪一段程序.下面看一个例子://a.phpPHP代码:-------------------------------------------------------------------------------- <?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这些商城网站搜索信息的程序。还有一个从阿里巴巴网站上读取商业信息和公司目录的程序也用到了此技术。 因为这两个程序都是要不断的链接它们的服务器读取信息并保存到数据库。 利用此技术正好消除了在等待响应时的瓶颈。 
仅以此抛砖引玉, 希望大家多来讨论~~~~~~~

解决方案 »

  1.   

    不能,不过可以通过多进程模拟多线程
    客户端开一个进程(浏览器进程),发送一个请求
    服务器端进行分解,然后在服务器端开n个进程(通过PHP的socket发送HTTP请求给服务器端的处理程序),然后得到结果=.=有一定的作用,用的不多!
      

  2.   

    不支持,因为不是每种操作系统都有“线程”的。再者线程的产生要在php解释器中进行,若以脚本控制则已失去意义了
      

  3.   

    windows下有线程的概念,我用asp.net可以实现到,但在php下不知应该怎样实现...
      

  4.   

    回复人: kendison(loving Ayumi!!!) ( ) 信誉:94  2004-08-25 08:43:00  得分: 0  
     
     
       我开多线程的目的主要是为了作大数据量的处理,比如一个数据库的更新操作需要十分钟,那我在服务器安全性许可的情况下应怎样执行(我的页面请求只允许30秒就超时,不想再设得大一点了),神仙的方法在这种情况下行不通
    --------------------------------------------------
    你除了延长响应时间应该没有其他好的办法了。
    提供一个思路。
    这些大量数据库更新的工作,能不能做成一个任务,放在晚间自动执行呢。
      
     
      

  5.   

    页面请求能不能用set_time_out函数来增加时限?
      

  6.   

    zhuomaocn(烦啊) ,不知道mysql怎样做这种任务。单机上可否设置成这样,开放81端口为我的站点,设为30秒超时,82端口设置为无超时限制,在81端口向82端口的页面发送request请求实现?可以的话php.ini应该怎样设置?
      

  7.   

    回复人: kendison(loving Ayumi!!!) ( ) 信誉:94  2004-08-25 09:21:00  得分: 0  
     
     
       zhuomaocn(烦啊) ,不知道mysql怎样做这种任务。单机上可否设置成这样,开放81端口为我的站点,设为30秒超时,82端口设置为无超时限制,在81端口向82端口的页面发送request请求实现?可以的话php.ini应该怎样设置?
    --------------------------------------------------------------------
    这个和数据库不达嘎。
    你把你的更新工作作成一个单独的PHP。在PHP里面把超时延长,最后再改成默认的。
    linux下,在cron里面设置一下,每天晚上几点运行这个PHP。就好像定时执行一个程序一样,不用考虑发送请求什么的。
    windows下,我没有做过,但windows也有自己的任务管理,设一下应该一样可以实现。
      
     
      

  8.   

    ini_set('max_execution_time', 1200); //延长至20分钟
      

  9.   

    我原来从CU上转过一篇关于这个问题的讨论,你搜一搜吧~~~我记得有个fork()函数,可以开辟新的进程~~而不是线程~~~
      

  10.   

    php的多线程,不太现实,可对向楼上的一样开个新的进程倒还是可行的.更向于加大延时的处理这样的方法.
      

  11.   

    php程序的每次执行就是开一个新的进程。
      

  12.   

    ==> 我开多线程的目的主要是为了作大数据量的处理,比如一个数据库的更新操作需要十分钟---不就是更新数据库吗就算要执行一个小时也是可以的呀!你管页面执行多长时间啊,
    页面执行时间与IE浏览器有关系的‘开始’->‘运行’->‘cmd’->
    %PathToPHP%\php.exe xxxxxxxx.php用命令行方式执行不就行了吗