Maison > développement back-end > tutoriel php > PHP implémente le multi-processus et le multi-threading

PHP implémente le multi-processus et le multi-threading

不言
Libérer: 2023-03-25 09:24:01
original
2912 Les gens l'ont consulté

Cet article présente principalement l'implémentation du multi-processus et du multi-threading en PHP. Il a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Instructions pour les débutants :


Processus orphelin : un processus parent se termine alors qu'un ou plusieurs de ses processus enfants sont toujours en cours d'exécution, ces processus enfants deviendront alors des processus orphelins. Le processus orphelin sera adopté par le processus d'initialisation (le numéro de processus est 1) et le processus d'initialisation terminera le travail de collecte de statut pour eux.

Processus zombie : un processus utilise fork pour créer un processus enfant si le processus enfant se termine et que le processus parent n'appelle pas wait ou waitpid pour obtenir le statut. Informations sur le processus enfant, Ensuite, le descripteur de processus du processus enfant est toujours enregistré dans le système. Ce processus est appelé processus zombie.

Dangers du processus zombie : Si le processus n'appelle pas wait/waitpid, Ensuite, les informations conservées ne seront pas divulguées et leur numéro de processus sera toujours occupé. Cependant, le numéro de processus pouvant être utilisé par le système est limité si un grand nombre de processus zombies sont générés. par le manque de numéros de processus disponibles. Le système ne peut pas générer de nouveaux processus. Il s'agit du risque de processus zombies et doit être évité. Tout processus enfant (sauf init) ne disparaît pas immédiatement après exit(), mais laisse une structure de données appelée processus zombie (Zombie), en attente du processus parent.

La solution au processus zombie qui a été généré : Tuez le processus parent et le processus zombie il génère des processus Devenir orphelins, ces processus orphelins seront repris par le processus d'initialisation, et le processus d'initialisation attendra() ces processus orphelins et libérera les ressources dans la table des processus système qu'ils occupent.

Solution au processus zombie

(1) Grâce au mécanisme de signal

Lorsque l'enfant le processus se termine Envoyez le signal SIGCHILD au processus parent, et le processus parent gère le signal SIGCHILD. Appelez l'attente dans la fonction de traitement du signal pour gérer le processus zombie.

(2) fork deux fois

La section 8.6 de « Programmation avancée dans un environnement Unix » est très détaillée. Le principe est de transformer le processus enfant en processus orphelin, de sorte que son processus parent devienne un processus d'initialisation et que le processus zombie puisse être traité via le processus d'initialisation.


Comparaison entre multi-processus et multi-thread

Dimensions de contraste

Multi-processus

Multi- fil de discussion

Résumé

Partage de données, synchronisation

Le partage de données est complexe et nécessite que les données IPC soient séparées et la synchronisation est simple

Parce que les données de processus sont partagées, le partage des données est simple, mais c'est aussi pour cette raison que la synchronisation est compliquée

Chacun a ses propres avantages

Mémoire, CPU

Occupe beaucoup de mémoire, commutation complexe, faible utilisation du processeur

Prendre peu de mémoire, commutation simple, utilisation élevée du processeur

Dominance des threads

Créer , détruire, changer

La création, la destruction et la commutation sont complexes et lentes

La création, la destruction et la commutation sont simples et rapides

Occupation des threads Excellent

Programmation et débogage

Programmation et débogage faciles

Programmation complexe, débogage compliqué

Domination des processus

Fiabilité

Les processus ne s'affecteront pas les uns les autres

Si un thread raccroche, l'ensemble du processus raccrochera

Le processus en profite

Distribué

Convient à la distribution multi-cœurs et multi-machines si ; une machine ne suffit pas, il est plus facile de s'étendre à plusieurs machines

Adapté à la distribution multicœur

Dominance des processus

1) Fils de discussion prioritaires qui doivent être fréquemment créés et détruits

Veuillez consulter la comparaison ci-dessus pour la raison.

L'application la plus courante de ce principe est le serveur web. Une connexion crée un thread, et lorsqu'elle est déconnectée, le thread est détruit si un processus est utilisé, le coût de création et de destruction est insupportable. 🎜>

2) Prioriser l'utilisation de threads qui nécessitent une grande quantité de calculs

La soi-disant grande quantité de calculs, bien sûr, consomme beaucoup de CPU et de commutateurs fréquemment. Dans ce cas, les threads sont les plus adaptés.

Les principes les plus courants de ce type sont le traitement d'images et le traitement d'algorithmes.

3) Les threads sont utilisés pour le traitement de corrélation forte, et les processus sont utilisés pour le traitement de corrélation faible

Qu'est-ce qu'une corrélation forte et une corrélation faible ? C’est difficile à définir en théorie, mais vous pouvez le comprendre avec un exemple simple.

Un serveur général doit effectuer les tâches suivantes : envoi et réception de messages, traitement des messages. « L'envoi et la réception de messages » et le « traitement des messages » sont des tâches faiblement liées, et le « traitement des messages » peut être divisé en « décodage des messages » et « traitement métier ». Ces deux tâches sont relativement beaucoup plus étroitement liées. Par conséquent, « l'envoi et la réception de messages » et le « traitement des messages » peuvent être conçus dans des processus distincts, et le « décodage des messages » et le « traitement métier » peuvent être conçus dans des threads distincts.

Bien entendu, cette méthode de division n'est pas statique et peut également être ajustée en fonction de la situation réelle.

4) Il peut être étendu aux processus utilisateur distribués multi-machines et aux threads utilisateur distribués multicœurs

Veuillez consulter la comparaison ci-dessus pour la raison.

5) Lorsque toutes les conditions sont remplies, utilisez la méthode qui vous est la plus familière et la meilleure dans

Quant à "partage de données, synchronisation", "programmation, débogage ", Comment choisir entre ce qu'on appelle "la complexité et la simplicité" dans les dimensions de la "fiabilité", je peux seulement dire : il n'y a pas de méthode de choix claire. Mais je peux vous expliquer un principe de sélection : si le multitraitement et le multithreading peuvent répondre aux exigences, alors choisissez celui que vous connaissez le mieux et dans lequel vous êtes le meilleur.

Ce qu'il faut rappeler est : bien que j'aie donné de nombreux principes de sélection, les candidatures réelles sont fondamentalement une combinaison de "processus + fil". Ne tombez pas vraiment dans une situation de choix.

Consommation des ressources :

Du point de vue du noyau, le but du processus est de servir de base à l'allocation des ressources système (temps CPU, mémoire, etc.). Un thread est un flux d'exécution d'un processus et l'unité de base de planification et de répartition du processeur. C'est une unité de base qui est plus petite qu'un processus et peut s'exécuter indépendamment.

Threads, ils utilisent le même espace d'adressage entre eux et partagent la plupart des données. L'espace nécessaire au démarrage d'un thread est bien inférieur à celui du démarrage d'un processus. De plus, le temps nécessaire pour basculer entre les threads est également loin. . Bien moins que le temps nécessaire pour basculer entre les processus. Selon les statistiques, en général, la surcharge d'un processus est environ 30 fois supérieure à celle d'un thread. Bien entendu, sur des systèmes spécifiques, ces données peuvent être considérablement différentes.

Méthode de communication :

La seule façon de transférer des données entre les processus est la communication, ce qui prend du temps et n'est pas pratique. La plupart des données de temps de thread sont partagées (non partagées dans la fonction thread), ce qui est rapide et pratique. Cependant, la synchronisation des données nécessite des verrous et une attention particulière doit être accordée aux variables statiques.

Avantages propres à Thread :

Amélioration de la réponse des applications, rendant les systèmes multi-CPU plus efficaces ; Le système d'exploitation veillera à ce que lorsque le nombre de threads n'est pas supérieur au nombre de processeurs, différents threads s'exécutent sur différents processeurs

Améliorer la structure du programme ; Un processus long et complexe peut être divisé en plusieurs threads et devenir plusieurs parties indépendantes ou semi-indépendantes. Un tel programme sera plus facile à comprendre et à modifier.

1. [Code] PHP implémente une opération parallèle multi-processus (peut être utilisé comme démon)

/**
 * 入口函数
 * 将此文件保存为 ProcessOpera.php
 * 在terminal中运行 /usr/local/php/bin/php ProcessOpera.php & 
 * 查看进程 ps aux|grep php
 */
 
 
ProcessOpera("runCode", array(), 8);
 
/**
 * run Code
 */
function runCode($opt = array()) {
   //需要在守护进程中运行的代码
}
 
/**
 * $func为子进程执行具体事物的函数名称
 * $opt为$func的参数 数组形式
 * $pNum 为fork的子进程数量
 */
function ProcessOpera($func, $opts = array(), $pNum = 1) {
    while(true) {
        $pid = pcntl_fork();
        if($pid == -1) {
            exit("pid fork error");
        }   
        if($pid) {
            static $execute = 0;
            $execute++;
            if($execute >= $pNum) {
                pcntl_wait($status);
                $execute--;
            }   
        } else {
            while(true) {
                //somecode
                $func($opts);
                sleep(1);
            }   
            exit(0);
        }   
    }   
}
Copier après la connexion

2. opération threadée

class My extends Thread {
    protected $name;
    public $runing;
    function __construct($name){
        $this->runing=1;
        $this->param=0;
        $this->name=$name;
    }
    public function run() {
        while($this->runing){
            if($this->param){
                $time=rand(1,5);
                echo 'I am thread '.$this->name.',pid: '.$this->getCreatorId().",param: {$this->param},need {$time}s\n"; 
                sleep($time);
                $this->param=0;
            }else{
                echo "Thread {$this->name} waiting...\n";
            }
            sleep(1);
        }
    }
}
$pool=array();
$pool[]=new My('a');
$pool[]=new My('b');
$pool[]=new My('c');
//开启所有线程
foreach ($pool as $w) {
    $w->start();
}
//派发任务
unset($w);
for($i=1;$i<10;$i++){
    $woker_content=$i;
    while(1){
        foreach($pool as $w){
            if(!$w->param){
                $w->param=$woker_content;
                echo "Thread {$w->name} empty,put param {$woker_content}.\n";
                break 2;
            }
        }
        sleep(1);    
    }
}


unset($w);
while(count($pool)){
    foreach ($pool as $k => $w) {
        if(!$w->param){
            $w->runing=false;
            unset($pool[$k]);
            echo "Thread {$w->name} end,exit!\n";
        }
    }
    sleep(1);
}


echo &#39;All thread end!&#39;;
Copier après la connexion

Recommandations associées :

Explication détaillée de cinq façons d'implémenter des tâches planifiées en 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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal