php實作類別多線程的方法總結_PHP教程

來源:互聯網
上載者:User
家都很清楚,php是不支援多線程的。但對於需要類似多線程功能的人來說確實是個頭疼的問題。好在有幾種方案可以進行解決,類似多線程功能。下面是本人總結的三種實現多線程類似的方法的方案,下面是三種方案與代碼執行個體。

1、curl_multi方法

當需要多線程的時候,可以用curl_multi一次性請求多個操作來完成,但curl走的是網路通訊,效率與可靠性就比較差了的。

function main(){       $sql = "select waybill_id,order_id from waybill where status>40 order by update_time desc limit 10 ";         $data = Yii::app()->db->createCommand($sql)->queryAll(); //yii 架構格式          foreach ($data as $k => $v) {              if ($k % 2 == 0) { //偶數發一個網址                  $send_data[$k]['url'] = '';                 $send_data[$k]['body'] = $v['waybill_id'];             } else { //奇數發送另外一個網址                     $send_data[$k]['url'] = 'http://www.abc.com';                 $send_data[$k]['body']=array($v['order_id'] => array('extra' => 16));             }         }            $back_data =sendMulitRequest($send_data);         var_dump($back_data);     }        function sendMulitRequest($send_data){            $params = array();            $curl = $text = array();               $handle = curl_multi_init();         foreach ($data as $k => $v) {             if (empty($v['url'])) {                 $v['url'] = "http://www.xxx.com"; //if url is empty,set defalut url             }             $reqBody = json_encode($v['body']);             $reqStream = array(                 'body' => $reqBody,             );             $encRequest = base64_encode(json_encode($reqStream));             $params['data'] = $encRequest;                $curl[$k] = curl_init();                curl_setopt($curl[$k], CURLOPT_URL, $v['url']);                curl_setopt($curl[$k], CURLOPT_POST, TRUE);             curl_setopt($curl[$k], CURLOPT_HEADER, 0);                curl_setopt($curl[$k], CURLOPT_POSTFIELDS, http_build_query($params));             curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1);                curl_multi_add_handle($handle, $curl[$k]);         }            $active = null;         do {             $mrc = curl_multi_exec($handle, $active);         } while ($mrc == CURLM_CALL_MULTI_PERFORM);            while ($active && $mrc == CURLM_OK) {             if (curl_multi_select($handle) != -1) {                 do {                     $mrc = curl_multi_exec($handle, $active);                 } while ($mrc == CURLM_CALL_MULTI_PERFORM);             }         }         foreach ($curl as $k => $v) {                if (curl_error($curl[$k]) == "") {                 $text[$k] = (string) curl_multi_getcontent($curl[$k]);             }             curl_multi_remove_handle($handle, $curl[$k]);             curl_close($curl[$k]);         }         curl_multi_close($handle);         return $text;        } function main(){     $sql = "select waybill_id,order_id from waybill where status>40 order by update_time desc limit 10 ";       $data = Yii::app()->db->createCommand($sql)->queryAll(); //yii 架構格式       foreach ($data as $k => $v) {           if ($k % 2 == 0) { //偶數發一個網址               $send_data[$k]['url'] = '';               $send_data[$k]['body'] = $v['waybill_id'];           } else { //奇數發送另外一個網址                $send_data[$k]['url'] = 'http://www.abc.com';               $send_data[$k]['body']=array($v['order_id'] => array('extra' => 16));           }       }        $back_data =sendMulitRequest($send_data);       var_dump($back_data);   }    function sendMulitRequest($send_data){        $params = array();        $curl = $text = array();         $handle = curl_multi_init();       foreach ($data as $k => $v) {           if (empty($v['url'])) {               $v['url'] = "http://www.xxx.com"; //if url is empty,set defalut url           }           $reqBody = json_encode($v['body']);           $reqStream = array(               'body' => $reqBody,           );           $encRequest = base64_encode(json_encode($reqStream));           $params['data'] = $encRequest;            $curl[$k] = curl_init();            curl_setopt($curl[$k], CURLOPT_URL, $v['url']);            curl_setopt($curl[$k], CURLOPT_POST, TRUE);           curl_setopt($curl[$k], CURLOPT_HEADER, 0);            curl_setopt($curl[$k], CURLOPT_POSTFIELDS, http_build_query($params));           curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1);            curl_multi_add_handle($handle, $curl[$k]);       }        $active = null;       do {           $mrc = curl_multi_exec($handle, $active);       } while ($mrc == CURLM_CALL_MULTI_PERFORM);        while ($active && $mrc == CURLM_OK) {           if (curl_multi_select($handle) != -1) {               do {                   $mrc = curl_multi_exec($handle, $active);               } while ($mrc == CURLM_CALL_MULTI_PERFORM);           }       }       foreach ($curl as $k => $v) {            if (curl_error($curl[$k]) == "") {               $text[$k] = (string) curl_multi_getcontent($curl[$k]);           }           curl_multi_remove_handle($handle, $curl[$k]);           curl_close($curl[$k]);       }       curl_multi_close($handle);       return $text;    }


2、通過stream_socket_client 方式

function sendStream() {                   $english_format_number = number_format($number, 4, '.', '');          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]['body'] = NoticeOrder::getSendData($v['waybill_id']);              } else {                     $send_data[$k]['body'] = array($v['order_id'] => array('extra' => 16));              }              $data = json_encode($send_data[$k]['body']);                 $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'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('h:i:s') . ".
"; 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); } function sendStream() { $english_format_number = number_format($number, 4, '.', ''); 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]['body'] = NoticeOrder::getSendData($v['waybill_id']); } else { $send_data[$k]['body'] = array($v['order_id'] => array('extra' => 16)); } $data = json_encode($send_data[$k]['body']); $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'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('h:i:s') . ".
"; 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('worker',array(1),2); 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('worker',array(1),2);  

http://www.bkjia.com/PHPjc/477201.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/477201.htmlTechArticle家都很清楚,php是不支援多線程的。但對於需要類似多線程功能的人來說確實是個頭疼的問題。好在有幾種方案可以進行解決,類似多線程...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.