Maison  >  Article  >  développement back-end  >  Le pool de processus PHP et l'algorithme de planification des interrogations réalisent le multitâche

Le pool de processus PHP et l'algorithme de planification des interrogations réalisent le multitâche

藏色散人
藏色散人avant
2019-11-13 14:09:122889parcourir

phper Veuillez comprendre la stratégie de planification des processus, la tranche de temps CPU, le contrôle des processus [création, destruction, recyclage, signaux de processus] et le flux d'exécution du processus et les groupes de processus de base, les principes d'interruption des signaux et la relation entre les processus.

Communication de processus :

Canal anonyme, canal nommé, file d'attente de messages, partage de mémoire, paire de sockets

Algorithme de planification de processus :

Sondages, distribution aléatoire, tableau de bord et autres stratégies, ou algorithmes de base tels qu'un pôle prioritaire, une file d'attente ou une pile [utilisez-le vous-même]

Pool de processus :

Si vous avez expérimenté TCP, sachez que pour pouvoir gérer plusieurs clients, vous devez utiliser la technologie de multiplexage IO [multiplexeur d'événements] ou plusieurs processus et multi-threads . Chaque fois qu'un client arrive, un processus ou un thread sera fork. Dans ce cas, le coût du changement de contexte est très élevé, nous créons donc d'abord un groupe de processus [pool de processus], et lorsque le client se connectera, ce sera le cas. L'algorithme [nous utilisons le sondage] est utilisé pour sélectionner un processus pour fournir des tâches pour effectuer le travail. De cette façon, il n'est pas nécessaire d'aller et venir entre la création et la destruction, ce qui améliore son efficacité.

Ce qui suit est l'implémentation de la version du code PHP

<?php
/**
 * Created by PhpStorm.
 * User: 1655664358@qq.com
 * Date: 2019/1/12
 * Time: 16:18
 */
$flag = 1;
class process
{
    public $pid;
    public $name;
    public $file;
    public $num;
}
class instance
{
    public $processIdx;
    public $proc = [];
    public $processNum;
}
function sigHandler($sigNo)
{
    global $flag;
    $flag = 0;
    echo "信号中断处理".PHP_EOL;
}
function processPool(instance &$instance,$num)
{
    if (!$instance||$num==0){
        fprintf(STDERR,"%s","参数错误");
        return 1;
    }
    $instance->processIdx = 0;
    $instance->processNum = $num;
    pcntl_signal(SIGINT,&#39;sigHandler&#39;);
    pcntl_signal(SIGTERM,&#39;sigHandler&#39;);
    $process = new process();
    for ($i=1;$i<=$num;$i++){
        $instance->proc[$i] = clone $process;
        $instance->proc[$i]->file = $i;
        $instance->proc[$i]->pid = pcntl_fork();
        $instance->processIdx = $i;
        if ($instance->proc[$i]->pid<0){
            exit("进程创建失败");
        }
        else if ($instance->proc[$i]->pid>0){
            //nothing
            continue;
        }else{
            worker($instance);
        }
    }
    master($instance);
    $exitProcess= [];
    while (1){
        for ($i=1;$i<=$num;$i++){
        //非阻塞方式回收子进程
            pcntl_waitpid($instance->proc[$i]->pid,$status,WNOHANG);
            if ($status){
                $exitProcess[] = $instance->proc[$i]->pid;
                fwrite(STDOUT,"worker#".$instance->proc[$i]->pid."-".$status,30);
            }
        }
        if (count($exitProcess)==$instance->processNum){
            exit(0);
        }
        usleep(1000);
    }
}
//简单的轮询算法  自己可以用队列,随机,链表,栈链,二叉树啥的折腾
function roundRobin(&$instance,$roll)
{
    /** @var instance $instance */
    return $instance->proc[$roll%$instance->processNum+1];
}
function master(&$instance)
{
    /** @var instance $instance */
    fprintf(STDOUT,"master 进程 %d\n",$instance->processIdx);
    global $flag;
    $roll = 0;
    while ($flag){
        pcntl_signal_dispatch();
        /** @var process $process */
        $process = roundRobin($instance,$roll++);
        echo "轮询的进程:".$process->pid.PHP_EOL;
        $file = $process->file;
        posix_mkfifo($file,0666);
        $fd = fopen($file,"w");
        fwrite($fd,"hi",2);
        sleep(1);
    }
    for ($i=1;$i<=$instance->processNum;$i++){
        posix_kill($instance->proc[$i]->pid,9);
    }
    fprintf(STDOUT,"master shutdown %d\n",$instance->processIdx);
}
function getProcess(&$instance)
{
    /** @var instance $instance */
    return $instance->proc[$instance->processIdx];
}
function worker(&$instance)
{
    /** @var process $process */
    $process = getProcess($instance);
    while (1){
        $file = $process->file;
        posix_mkfifo($file,0666);
        $fd = fopen($file,"r");
        $content = fread($fd,10);
        fprintf(STDOUT,"worker#%d读取的内容:%s file=%d\n",posix_getpid(),$content,$file);
    }
    exit(0);
}
$instance = new instance();
processPool($instance,5);

Effet

Le pool de processus PHP et lalgorithme de planification des interrogations réalisent le multitâche

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