Maison  >  Article  >  développement back-end  >  Solution multithread php simple

Solution multithread php simple

烟雨青岚
烟雨青岚avant
2020-06-16 13:15:404737parcourir

Solution multithread php simple

Solution multi-thread PHP simple

Lorsque nous faisons des projets, nous avons certains besoins, notamment en matière de données. Le traitement des réponses prend beaucoup de temps. Puisque PHP est un langage de script à cycle de vie court, après les 30 secondes par défaut, le traitement des données de PHP n'est pas terminé et le cycle de vie de PHP est terminé.

À l'heure actuelle, vous devez utiliser une stratégie de traitement simultané asynchrone, c'est-à-dire plusieurs requêtes pouvant être émises par un seul appel PHP. Ces requêtes ne sont pas exécutées en séquence, mais peuvent être exécutées de manière asynchrone et. simultanément. Certaines requêtes sont utilisées dans les données de processus en arrière-plan, certaines requêtes sont utilisées pour accepter l'état de la réponse en arrière-plan et effectuer des interactions simples avec les utilisateurs en fonction de l'état.

Mais voici le problème. Nous savons tous que PHP lui-même ne prend pas en charge le multi-threading, alors comment devrions-nous implémenter le multi-threading en PHP ?

1. Trois méthodes de simulation php pour réaliser le multi-threading

1. PHP multi-threading sous Linux

Les éléments suivants sont la source Puisque la fonction pcntl_fork de PHP. Étant donné que cette fonction dépend de l'implémentation du fork du système d'exploitation, les éléments abordés dans cet article ne s'appliquent qu'à Linux/Unix. Jetons donc d'abord un coup d'œil à l'utilisation de cette fonction. Le manuel PHP dit ceci :

<?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
}
?>

Créez un processus enfant via pcntl_fork Si la valeur de retour est -1, alors la création du processus enfant a échoué. La création a réussi. L'ID du processus sera renvoyé au processus parent et 0 sera renvoyé au processus enfant. C'est difficile à comprendre, il devrait donc être écrit comme ceci :

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

Ce changement sera. facilitez la compréhension. Si votre processus parent veut savoir que le processus enfant se termine normalement, vous pouvez ajouter le pcntl_wait précédent.

2. Grâce à la méthode 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
Host:" . $host . "
";  
        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!
"; 
        break; 
      }  
    }  
    print_r($result); 
  
  }

3. Remplacez le multi-threading par le multi-processus

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);

2. La vraie façon de réaliser le multi-threading en php

La vraie façon de réaliser le multi-threading en php peut être réalisée en installant l'extension php pthread.

Cliquez ici pour télécharger https://github.com/krakjoe/pthreads Mais ce téléchargement est la version 3, qui ne peut être utilisée qu'avec php 7. Nous devons utiliser la version 2

Solution multithread php simple

Rafraîchissez ensuite la page comme suit, faites glisser vers le bas :

Solution multithread php simple

Solution multithread php simple

Retrouvez la version 2 sur la page suivante page

Télécharger, cette v2 ne peut être utilisée qu'avec php5

Télécharger et installer :

Ou, vous pouvez télécharger directement comme ceci :

cd /tools  
   wget https://github.com/krakjoe/pthreads/archive/v2.0.10.zip  
   unzip   v2.0.10.zip  
   cd pthreads-2.0.10  
   /usr/local/php/bin/phpize  
   ./configure --with-php-config=/usr/local/php/bin/php-config    
   make  
   make install

Remarque : Votre php doit être activé lors de la compilation –enable-maintainer-zts

./configure --prefix=/usr/local/php --disable-fileinfo --enable-fpm --with-config- file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-openssl --with-zlib --with-curl --enable-ftp --with-gd - -with-xmlrpc --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-gd-native-ttf --enable-mbstring --with-mcrypt=/usr/local/ libmcrypt --enable-zip --with-mysql=/usr/local/mysql --without-pear --enable-maintainer-zts

vim /etc/php.ini 
添加
extension=pthreads.so

Redémarrer php /etc/init.d/php-fpm restart

Merci à tous d'avoir lu, j'espère que vous en bénéficierez beaucoup.

Tutoriel recommandé : "Tutoriel php"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer