首頁  >  文章  >  後端開發  >  php多執行緒模擬實作的三種方法介紹

php多執行緒模擬實作的三種方法介紹

黄舟
黄舟原創
2017-11-11 13:40:452418瀏覽

我們在做專案的時候,有些需求,特別是資料的回應處理需要花費大量的時間,我們都知道php本身是不支援多執行緒的,那麼應該怎麼做php的多執行緒呢?

1、linux下的php多執行緒

#下面所講的東西是源自php的pcntl_fork函數.因為這個函數依賴作業系統fork的實作,所以本文所講的東西只適用於linux/unix。那麼先看看這個函數的用法吧.php手冊上是這麼說的:

<?php
$pid = pcntl_fork();if ($pid == -1) {         
die(&#39;could not fork&#39;);
} else if ($pid) {         
// we are the parent
         pcntl_wait($status); /
/Protect against Zombie children} else {         
// we are the child}?>

透過pcntl_fork建立一個子進程,如果傳回值是-1的話,那麼說明子進程創建失敗.創建成功的進程id會返回給父進程,0返回給子進程.不好理解吧,所以應該這樣寫:

<?php
$pid = pcntl_fork();if($pid == -1){         //创建失败咱就退出呗,没啥好说的
         die(&#39;could not fork&#39;);
}else{        if($pid){                //从这里开始写的代码是父进程的,因为写的是系统程序,记得退出的时候给个返回值
                exit(0);
        }        else{                //从这里开始写的代码都是在新的进程里执行的,同样正常退出的话,最好也给一个返回值
                exit(0);
        }
}?>

這樣一改好理解多了,如果你父進程希望知道子進程正常退出的話,可以加上前面的pcntl_wait。

2.透過stream_socket_client 方式

function sendStream() { 
    $english_format_number = number_format($number, 4, &#39;.&#39;, &#39;&#39;); 
  
    echo $english_format_number;  
    exit(); 
    $timeout = 10; 
    $result = array(); 
    $sockets = array(); 
    $convenient_read_block = 8192; 
    $host = "test.local.com"; 
    $sql = "select waybill_id,order_id from xm_waybill where status>40 order by update_time desc limit 1 ";  
    $data = Yii::app()->db->createCommand($sql)->queryAll(); 
    $id = 0; 
  
    foreach ($data as $k => $v) { 
      if ($k % 2 == 0) { 
        $send_data[$k][&#39;body&#39;] = NoticeOrder::getSendData($v[&#39;waybill_id&#39;]); 
  
      } else { 
        $send_data[$k][&#39;body&#39;] = array($v[&#39;order_id&#39;] => array(&#39;extra&#39; => 16));  
      }  
      $data = json_encode($send_data[$k][&#39;body&#39;]); 
      $s = stream_socket_client($host . ":80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT); 
      if ($s) {  
        $sockets[$id++] = $s; 
        $http_message = "GET /php/test.php?data=" . $data . " HTTP/1.0\r\nHost:" . $host . "\r\n\r\n";  
        fwrite($s, $http_message); 
      } else {  
        echo "Stream " . $id . " failed to open correctly."; 
      }  
    } 
  
    while (count($sockets)) { 
  
      $read = $sockets; 
  
      stream_select($read, $w = null, $e = null, $timeout); 
       if (count($read)) {  
        /* stream_select generally shuffles $read, so we need to 
         compute from which socket(s) we&#39;re reading. */
        foreach ($read as $r) { 
  
          $id = array_search($r, $sockets); 
          $data = fread($r, $convenient_read_block); 
          if (strlen($data) == 0) { 
            echo "Stream " . $id . " closes at " . date(&#39;h:i:s&#39;) . ".<br>  "; 
            fclose($r); 
             unset($sockets[$id]); 
          } else { 
            $result[$id] = $data; 
          } 
        } 
      } else {  
        /* A time-out means that *all* streams have failed 
         to receive a response. */
        echo "Time-out!\n"; 
        break; 
      }  
    }  
    print_r($result); 
  
  }

3、透過多進程取代多執行緒

#
function daemon($func_name,$args,$number){ 
  while(true){ 
    $pid=pcntl_fork(); 
    if($pid==-1){ 
      echo "fork process fail"; 
      exit(); 
    }elseif($pid){//创建的子进程 
  
      static $num=0; 
      $num++; 
      if($num>=$number){ 
        //当进程数量达到一定数量时候,就对子进程进行回收。 
        pcntl_wait($status); 
  
        $num--; 
      }  
    }else{ //为0 则代表是子进程创建的,则直接进入工作状态 
  
      if(function_exists($func_name)){ 
        while (true) { 
          $ppid=posix_getpid(); 
          var_dump($ppid); 
          call_user_func_array($func_name,$args); 
          sleep(2); 
        } 
      }else{ 
        echo "function is not exists"; 
      } 
      exit();   
    } 
  } 
}  function worker($args){  
  //do something 
  }  
daemon(&#39;worker&#39;,array(1),2);

總結:

#php中不可以使用多執行緒了,其實我們大家都是知道的,但我們可以透過很多方法讓他實現,本文就是介紹PHP中多執行緒實作方法。希望對你有幫助!

相關推薦:

#php多執行緒的實作實例


php多執行緒一種實作方法—shell


#PHP多執行緒小案例


#關於PHP多執行緒的處理問題

以上是php多執行緒模擬實作的三種方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn