Maison  >  Article  >  développement back-end  >  Tâches parallèles de traitement multi-processus PHP

Tâches parallèles de traitement multi-processus PHP

小云云
小云云original
2018-03-28 14:20:542201parcourir

Cet article utilise des exemples pour expliquer comment utiliser PHP pour le traitement de tâches simultanées dans l'environnement Linux et comment utiliser Pipe pour la synchronisation des données entre les processus. Écrit relativement simplement, sous forme de mémo.

PHP multi-processus

Utilisez la fonction multi-processus via la série de fonctions pcntl_XXX. Remarque : pcntl_XXX ne peut s'exécuter que dans l'environnement php CLI (ligne de commande). Dans l'environnement du serveur Web, des résultats imprévisibles se produiront, veuillez l'utiliser avec prudence !

Pipe PIPE

Pipe est utilisé pour transporter des données de communication entre les abréviations. Pour faciliter la compréhension, un canal peut être comparé à un fichier. Le processus A écrit des données dans le canal P, puis le processus B lit les données dans le canal P. L'API d'opération de pipeline fournie par PHP est fondamentalement la même que l'API d'exploitation de fichiers. Sauf que la fonction posix_mkfifo est utilisée pour créer un pipeline, les opérations de lecture et d'écriture sont les mêmes que les fonctions d'opération de fichier. Bien sûr, vous pouvez utiliser directement des fichiers pour simuler des tuyaux, mais vous ne pourrez alors pas utiliser les fonctionnalités des tuyaux.

Processus zombie

Lorsque le processus enfant se termine, le processus parent ne l'attend pas (en appelant wait ou waitpid), alors toutes les ressources ne seront pas libérées après la fin du processus enfant (un gaspillage !), ce type de processus est appelé processus zombie, qui stocke les données pertinentes à la fin du processus enfant. S'il y a trop de processus zombie, cela occupera beaucoup de ressources système (telles que la mémoire) et affectera les performances de la machine. .

Code

/** 
 * this is a demo for php fork and pipe usage. fork use 
 * to create child process and pipe is used to sychoroize 
 * the child process and its main process. 
 * @author bourneli 
 * @date: 2012-7-6 
 */  
   
define("PC", 10); // 进程个数  
define("TO", 4); // 超时  
define("TS", 4); // 事件跨度,用于模拟任务延时  
   
if (!function_exists('pcntl_fork')) {  
    die("pcntl_fork not existing");  
}  
   
// 创建管道  
$sPipePath = "my_pipe.".posix_getpid();  
if (!posix_mkfifo($sPipePath, 0666)) {  
    die("create pipe {$sPipePath} error");  
}  
   
// 模拟任务并发  
for ($i = 0; $i < PC; ++$i ) {  
    $nPID = pcntl_fork(); // 创建子进程  
    if ($nPID == 0) {  
        // 子进程过程  
        sleep(rand(1,TS)); // 模拟延时  
        $oW = fopen($sPipePath, &#39;w&#39;);  
        fwrite($oW, $i."\n"); // 当前任务处理完比,在管道中写入数据  
        fclose($oW);  
        exit(0); // 执行完后退出  
    }  
}  
   
// 父进程  
$oR = fopen($sPipePath, &#39;r&#39;);  
stream_set_blocking($oR, FALSE); // 将管道设置为非堵塞,用于适应超时机制  
$sData = &#39;&#39;; // 存放管道中的数据  
$nLine = 0;  
$nStart = time();  
while ($nLine < PC && (time() - $nStart) < TO) {  
    $sLine = fread($oR, 1024);  
    if (empty($sLine)) {  
        continue;     
    }     
       
    echo "current line: {$sLine}\n";  
    // 用于分析多少任务处理完毕,通过‘\n’标识  
    foreach(str_split($sLine) as $c) {  
        if ("\n" == $c) {  
            ++$nLine;  
        }  
    }  
    $sData .= $sLine;  
}  
echo "Final line count:$nLine\n";  
fclose($oR);  
unlink($sPipePath); // 删除管道,已经没有作用了  
   
// 等待子进程执行完毕,避免僵尸进程  
$n = 0;  
while ($n < PC) {  
    $nStatus = -1;  
    $nPID = pcntl_wait($nStatus, WNOHANG);  
    if ($nPID > 0) {  
        echo "{$nPID} exit\n";  
        ++$n;  
    }  
}  
   
// 验证结果,主要查看结果中是否每个任务都完成了  
$arr2 = array();  
foreach(explode("\n", $sData) as $i) {// trim all  
    if (is_numeric(trim($i))) {  
        array_push($arr2, $i);    
    }  
}  
$arr2 = array_unique($arr2);  
if ( count($arr2) == PC) {    
    echo &#39;ok&#39;;   
} else {  
    echo  "error count " . count($arr2) . "\n";  
    var_dump($arr2);  
}

Recommandations associées :

Explication détaillée des exemples de programmation multi-processus 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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn