<?php   
echo "Program starts at ". date('h:i:s') . ".\n";   
$timeout = 3;    
$sockets = array();  //socket句柄数组   
//一次发起多个请求   
$delay = 0;   
while ($delay++ < 3)    
{   
    $sh = stream_socket_client("localhost:80", $errno, $errstr, $timeout,   
            STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);    
    /* 这里需要稍微延迟一下,否则下面fwrite中的socket句柄不一定能真正使用  
       这里应该是PHP的一处bug,查了一下,官方bug早在08年就有人提交了  
       我的5.2.8中尚未解决,不知最新的5.3中是否修正  
    */  
    usleep(10);    
    if ($sh) {    
        $sockets[] = $sh;    
        $http_header = "GET /test.php?n={$delay} HTTP/1.0\r\n";   
        $http_header .= "Host: localhost\r\n";   
        $http_header .= "Accept: */*\r\n";   
        $http_header .= "Accept-Charset: *\r\n";    
        $http_header .= "\r\n";    
        fwrite($sh, $http_header);   
    } else {    
        echo "Stream failed to open correctly.\n";   
    }    
}    
//非阻塞模式来接收响应   
$result = array();    
$read_block_size = 8192;   
while (count($sockets))    
{    
    $read = $sockets;    
    $n = stream_select($read, $w=null, $e=null, $timeout);    
    //if ($n > 0) //据说stream_select返回值不总是可信任的   
    if (count($read))    
    {   
        /* stream_select generally shuffles $read, so we need to   
           compute from which socket(s) we're reading. */   
        foreach ($read as $r)    
        {    
            $id = array_search($r, $sockets);    
            $data = fread($r, $read_block_size);    
            if (strlen($data) == 0)    
            {    
                echo "Stream {$id} closes at " . date('h:i:s') . ".\n";   
                fclose($r);    
                unset($sockets[$id]);    
            } else {    
                if (!isset($result[$id])) $result[$id] = '';   
                $result[$id] .= $data;    
            }    
        }    
    } else {    
        echo "Time-out!\n";   
        break;   
    }    
}    
这条随便找都能找到的模拟多线程的代码,虽然能监控到sock的是否在执行,
但不能解决超时问题(用来模拟线程的代码,我们不可能知道它需要多少时间完成任务),
如果被监控页面(test.php)加入ignore_user_abort(true); set_time_limit(0);虽然能解决超时问题,
但是上面的模拟线程代码已经不能想关闭就关闭它的执行了,
本人刚学php,希望经验丰富的前辈能指教一下,谢谢!

解决方案 »

  1.   

    多线程是PHP的软肋,不要试图去模拟.其实PHP当初设计的时候主要是由Web服务器来调用的,Web服务器实现多线程就行了.
      

  2.   

    给你的传送门!
    转载的一篇文章!
    http://user.qzone.qq.com/9399428/blog/1289547454
      

  3.   

    用curl吧,事实证明完全解决你的困扰。可以有效解决timeout问题curl_multi 多线程真正应用。
      

  4.   


    呵呵!忘记设置了提问了!
    主要是pcntl_fork的使用~你查下相关资料就知道了!
      

  5.   

    pcntl_fork在win不能使用吧?????