現在功能十分簡單而已,大家互相學習一下吧,多多指教//********************************************************Thread.php<?php
/**************************************************************************************
class Thread   
version:alpha
by:Alex Lau
email:[email protected]
If you got any questions, feel free to ask me.In this class, there are six properties
var $func;  //The function name that you want to call
var $arg; //The arguments you want to pass in
var $thisFileName; //This file's name
var $fp; //File pointer
var $host; //Host
var $port; //Port
And there is four methods,
void Thread(string $host, [int $port = 80]) // constructor
void setFunc(string $func,array $arg) 
$func is a string of the function name
$arg is an array of the arguments
Usage:
$arg = array ( 2, 3);
$func = "test";
The method will call test(2,3).
void start()   To start the thread
mixed getreturn()   To get the return value from the function that called by setFunc
void setPort()   To set the port
void setHost()   To set the hostSince serialize() does not support the resource type, this class cannot be used to pass in or return the resource type.
**************************************************************************************//**************************************************************************************
class Thread    
version:alpha
by:Alex Lau
email:[email protected]
有問題的話就問我吧這個類別中有六個屬性
var $func; //你要呼叫的function名稱
var $arg; //你要傳遞的參數
var $thisFileName;//include這個物件的檔名
var $fp; //檔案指針
var $host;  //伺服器的host
var $port; //伺服器的端口
有六個方法
void Thread(string $host, [int $port = 80]) //建構子
void setFunc(string $func,array $arg) 
$func 是function的名稱
$arg 是一個參數的數組(array)
例如:
$arg = array ( 2, 3);
$func = "test";
此物件會呼叫 test(2,3).
void start()  //開始線程
mixed getreturn() //取得線程返回的數值
void setPort(int $port) //設定端口
void setHost(string $host) //設定主機位址由於serialize()不支援resource,這個類別也不支援傳遞或返回resource。
**************************************************************************************/class Thread{
var $func;
var $arg;
var $thisFileName;
var $fp;
var $host;
var $port;
function Thread($host,$port=""){
$this->host = $host;
if ($port != ""){
$this->port = $port;
}else{
$this->port = 80;
}
$this->thisFileName = $_SERVER["SCRIPT_NAME"];
}
function setFunc($func,$arg=false){
$i=0;
$this->arg = "";
if ($arg){
foreach ($arg as $argument){
$this->arg .= "&a[]=".urlencode(serialize($argument));
}
}
$this->func = $func;
}
function setPort($port){
$this->port = $port;
}
function setHost($host){
$this->host = $host;
}
function start(){
$this->fp = fsockopen($this->host,30);
$header = "GET ".$this->thisFileName."?threadrun=1&f=".urlencode($this->func).$this->arg." HTTP/1.1\r\n";
$header .= "Host: ".$this->host."\r\n";
$header .= "Connection: Close\r\n\r\n";
fputs($this->fp,$header);
}
function getreturn(){
$flag=false;
while (!feof($this->fp)) {
$buffer = fgets($this->fp, 4096);
if ($flag){
$output .= $buffer;
}
if (trim($buffer) == ""){
$flag = true;
}
}
return unserialize(trim($output));
}
}
if (isset($_GET['threadrun'])){
$arg_str = "";
$i=0;
if (isset($_GET['a'])){
foreach($_GET['a'] as $argument){
if ($i == 0){
$arg_str .= unserialize($argument);
}else{
$arg_str .= ",".unserialize($argument);
}
$i++;
}
}
eval("\$return = ".$_GET['f']."(".$arg_str.");");
echo serialize($return);
exit;
}?> 
//*****************************************************test.php
<?php
include_once("Thread.php");
function test($test_arg){
return "傳進來的參數為:".$test_arg."。<br />";
//return "Pass in variable:".$test_arg.".<br />";
}
function test_2($test_arg){
$start = time();
while (time() < $start+$test_arg){

}
return $test_arg."秒己經過了。<br />";
//return $test_arg."seconds have passed.<br />";
}$program_start_time = time();$thread_a = new Thread("localhost",30);
$thread_a->setFunc("test",array(100));
$thread_a->start();$thread_b = new Thread("localhost",30);
$thread_b->setFunc("test_2",array(2));
$thread_b->start();$thread_c = new Thread("localhost",30);
$thread_c->setFunc("test_2",array(3));
$thread_c->start();echo $thread_a->getreturn();
echo $thread_b->getreturn();
echo $thread_c->getreturn();echo "主程式運行了".(time()-$program_start_time)."秒。<br />";
//echo "Main Program has run ".(time()-$program_start_time)."seconds。<br />";?>

解决方案 »

  1.   

    //********************************************************Thread.php//修正版,之前一直要用port 30,現在改了<?php
    /**************************************************************************************
    class Thread   
    version:alpha
    by:Alex Lau
    email:[email protected]
    If you got any questions, feel free to ask me.In this class, there are six properties
    var $func;  //The function name that you want to call
    var $arg;//The arguments you want to pass in
    var $thisFileName; //This file's name
    var $fp;//File pointer
    var $host;//Host
    var $port;//Port
    And there is four methods,
    void Thread(string $host, [int $port = 80]) // constructor
    void setFunc(string $func,array $arg) 
    $func is a string of the function name
    $arg is an array of the arguments
    Usage:
    $arg = array ( 2, 3);
    $func = "test";
    The method will call test(2,3).
    void start()  To start the thread
    mixed getreturn()  To get the return value from the function that called by setFunc
    void setPort()  To set the port
    void setHost()  To set the hostSince serialize() does not support the resource type, this class cannot be used to pass in or return the resource type.
    **************************************************************************************//**************************************************************************************
    class Thread    
    version:alpha
    by:Alex Lau
    email:[email protected]
    有問題的話就問我吧這個類別中有六個屬性
    var $func;//你要呼叫的function名稱
    var $arg;//你要傳遞的參數
    var $thisFileName;//include這個物件的檔名
    var $fp;//檔案指針
    var $host; //伺服器的host
    var $port;//伺服器的端口
    有六個方法
    void Thread(string $host, [int $port = 80]) //建構子
    void setFunc(string $func,array $arg) 
    $func 是function的名稱
    $arg 是一個參數的數組(array)
    例如:
    $arg = array ( 2, 3);
    $func = "test";
    此物件會呼叫 test(2,3).
    void start()  //開始線程
    mixed getreturn()//取得線程返回的數值
    void setPort(int $port) //設定端口
    void setHost(string $host) //設定主機位址由於serialize()不支援resource,這個類別也不支援傳遞或返回resource。
    **************************************************************************************/class Thread{
    var $func;
    var $arg;
    var $thisFileName;
    var $fp;
    var $host;
    var $port;
    function Thread($host,$port=""){
    $this->host = $host;
    if ($port != ""){
    $this->port = $port;
    }else{
    $this->port = 80;
    }
    $this->thisFileName = $_SERVER["SCRIPT_NAME"];
    }
    function setFunc($func,$arg=false){
    $i=0;
    $this->arg = "";
    if ($arg){
    foreach ($arg as $argument){
    $this->arg .= "&a[]=".urlencode(serialize($argument));
    }
    }
    $this->func = $func;
    }
    function setPort($port){
    $this->port = $port;
    }
    function setHost($host){
    $this->host = $host;
    }
    function start(){
    $this->fp = fsockopen($this->host,$this->port);
    $header = "GET ".$this->thisFileName."?threadrun=1&f=".urlencode($this->func).$this->arg." HTTP/1.1\r\n";
    $header .= "Host: ".$this->host."\r\n";
    $header .= "Connection: Close\r\n\r\n";
    fputs($this->fp,$header);
    }
    function getreturn(){
    $flag=false;
    while (!feof($this->fp)) {
    $buffer = fgets($this->fp, 4096);
    if ($flag){
    $output .= $buffer;
    }
    if (trim($buffer) == ""){
    $flag = true;
    }
    }
    return unserialize(trim($output));
    }
    }
    if (isset($_GET['threadrun'])){
    $arg_str = "";
    $i=0;
    if (isset($_GET['a'])){
    foreach($_GET['a'] as $argument){
    if ($i == 0){
    $arg_str .= unserialize($argument);
    }else{
    $arg_str .= ",".unserialize($argument);
    }
    $i++;
    }
    }
    eval("\$return = ".$_GET['f']."(".$arg_str.");");
    echo serialize($return);
    exit;
    }?> 
      

  2.   

    $thread_a = new Thread("localhost",80);
    $thread_a->setFunc("test_2",array(100));
    $thread_a->start();$thread_b = new Thread("localhost",80);
    $thread_b->setFunc("test_2",array(2));
    $thread_b->start();$thread_c = new Thread("localhost",80);
    $thread_c->setFunc("test_2",array(3));
    $thread_c->start();三个就会超时了,看来并不是真正的并行吧?
      

  3.   

    你$thread_a都是呼叫test_2,而且傳入參數是100,即等100秒才返回,那不超時才怪= =
      

  4.   

    其实没什么,因为一般的服务器都开启了keep live 这功能,这样不管你开多少个所谓的线程,实际上服务器对同一客户端还是只有一个连接的
      

  5.   

    这么热闹,我也贴一个我做的PHP模拟多线程<?
    set_time_limit(600);
    header('Content-type: text/html; charset=utf-8');
    require_once('includes/conn.php'); //require database connectionsession_start();//多线程发送函数,提交到b.php========================================================
    function smsSend($IswNumsID,$IswNumsUsername,$IswNumsUserID,$mobiles,$content,$contenttype){ $req='IswNumsID='.$IswNumsID;
    $req.='&IswNumsUsername='.$IswNumsUsername;
    $req.='&IswNumsUserID='.$IswNumsUserID;
    $req.='&mobiles='.$mobiles;
    $req.='&content='.$content;
    $req.='&contenttype='.$contenttype;


    //$header = "POST /sms/c.php HTTP/1.0\r\n";
    $header = "POST http://www.sms4hk.com/b.php HTTP/1.0\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
    $fp = fsockopen ('www.***.com',80,$errno,$errstr,30);
    if($fp){
    fputs ($fp, $header . $req);
    echo '.';

    }else{
    echo 'http error';
    }
    }
    //================================================================================//搜索数据库得到最大的线程数和当前的线程数
    $rsCount=$db->query_first("select IswNumsMaxSendCount,IswNumsNowSendCount from sms_systemseting");
    //用最大线程数减当前的线程数得到下一次应该启动多少个线程
    $sendCount=doubleval($rsCount['IswNumsMaxSendCount'])-doubleval($rsCount['IswNumsNowSendCount']);
    if($sendCount<0){
    $sendCount=0;
    }//搜索要发送的数据
    $query=$db->query("select * from sms_sendlist where IswNumsState=0 and IswNumsErrorNum<=3 and (IswNumsType=1 or IswNumsSendTime<=now()) order by IswNumsAddTime asc limit 0,$sendCount");while($rs=$db->fetch_array($query)){
    //将状态改为正在发送,以免这条还没发完,下一条又在开始发送了
    $db->query("update sms_sendlist set IswNumsState=1 where IswNumsID='".$rs['IswNumsID']."'");
    //开始发送
    smsSend($rs['IswNumsID'],$rs['IswNumsUsername'],$rs['IswNumsUserID'],$rs['IswNumsMobiles'],$rs['IswNumsContent'],$rs['IswNumsContentType']);
    //将当前的线程数+1
    $db->query("update sms_systemseting set IswNumsNowSendCount=IswNumsNowSendCount+1");
    }
    ?>