Maison > développement back-end > PHP8 > le corps du texte

PHP8.1 Fiber exécute plusieurs tâches de manière croisée (avec explication détaillée du code)

藏色散人
Libérer: 2023-02-17 12:30:02
avant
4074 Les gens l'ont consulté

Prenez la boucle for que tout le monde écrit habituellement comme exemple. Comme pour aller, vous pouvez écrire deux

et écrire une boucle dans chacun pour entrer en même temps. Vous pouvez voir que la sortie est alternative. Dans les versions précédentes de PHP, si vous n'ouvriez qu'un seul cli et écriviez plusieurs boucles for, sa sortie devait être séquentielle. La sortie croisée ne peut pas être obtenue (c'est-à-dire qu'après plusieurs exécutions dans la première boucle, b peut être exécuté à nouveau, et b peut être exécuté pendant un certain temps, puis A peut être exécuté).

Maintenant, grâce à la fibre, nous pouvons également réaliser cette opération. [Apprentissage recommandé : goTutoriel vidéo PHP

]

Le code suivant peut réaliser l'exécution croisée de deux boucles. Vous pouvez même contrôler la fréquence d'exécution de deux programmes (par exemple, A est exécuté 3 fois et B est exécuté une fois)

<?php
$t1    = false;
$t2    = false;
$reg   = [];
$reg[] = new \Fiber(function () use (&$t1) {
    for ($i = 1; $i < 10; $i++) {
        echo $i;
        echo PHP_EOL;
        \Fiber::suspend();

    }
    $t1 = true;
});


$reg[] = new \Fiber(function () use (&$t2) {
    for ($i = 1; $i < 10; $i++) {
        echo $i;
        echo PHP_EOL;
        \Fiber::suspend();
    }
    $t2 = true;
});

$startTag = true;
while (count($reg) > 1) {

    if ($startTag) foreach ($reg as $pI) {
        $pI->start();
        $startTag = false;
    }

    foreach ($reg as $pI) {
        $pI->resume();
    }

    if ($t1 === true && $t2 === true) {
        break;
    }
}
Copier après la connexion
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
Copier après la connexion

Vous pouvez même contrôler la fréquence d'exécution de deux boucles Par exemple, après que la première boucle soit exécutée 3 fois. , la deuxième boucle s'exécute une fois. Le code est le suivant

<?php
$reg = [];
$fId = 1;


$reg[$fId] = new \Fiber(function () use (&$reg, $fId) {
    for ($i = 1; $i < 10; $i++) {
        echo $fId . &#39;:&#39; . $i;
        echo PHP_EOL;
        if ($i % 3 == 0) {
            \Fiber::suspend();
        }
    }
    unset($reg[$fId]);
});
$fId++;

$reg[$fId] = new \Fiber(function () use (&$reg, $fId) {
    for ($i = 1; $i < 10; $i++) {
        echo $fId . &#39;:&#39; . $i;
        echo PHP_EOL;
        \Fiber::suspend();
    }
    unset($reg[$fId]);
});

$startTag = true;
while (count($reg) > 0) {
    if ($startTag) foreach ($reg as $pI) {
        $pI->start();
        $startTag = false;
    }
    foreach ($reg as $pI) {
        $pI->resume();
    }
}
Copier après la connexion
1:1
1:2
1:3
2:1
1:4
1:5
1:6
2:2
1:7
1:8
1:9
2:3
2:4
2:5
2:6
2:7
2:8
2:9
Copier après la connexion

Compléter via notification par message

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: &#39;Sname&#39;,
    description: &#39;Add a short description for your command&#39;,
)]
class SnameCommand extends Command
{
    protected function configure(): void
    {
        $this
            ->addArgument(&#39;arg1&#39;, InputArgument::OPTIONAL, &#39;Argument description&#39;)
            ->addOption(&#39;option1&#39;, null, InputOption::VALUE_NONE, &#39;Option description&#39;);
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $t1  = false;
        $t2  = false;
        $reg = [];
        $fId = 1;


        $reg[] = new \Fiber(function () use ($fId) {
            for ($i = 1; $i < 10; $i++) {
                echo $fId . &#39;:&#39; . $i;
                echo PHP_EOL;
                if ($i % 3 == 0) {
                    \Fiber::suspend(new SuspendData(Status::Running));
                }
            }
            \Fiber::suspend(new SuspendData(Status::Stop));

        });
        $fId++;

        $reg[] = new \Fiber(function () use ($fId) {
            for ($i = 1; $i < 10; $i++) {
                echo $fId . &#39;:&#39; . $i;
                echo PHP_EOL;
                \Fiber::suspend(new SuspendData(Status::Running));
            }
            \Fiber::suspend(new SuspendData(Status::Stop));
        });

        $startTag = true;
        while (count($reg) > 0) {
            if ($startTag) foreach ($reg as $pI) {
                $pI->start();
                $startTag = false;
            }
            foreach ($reg as $key => $pI) {
                $r = $pI->resume();
                if ($r->status === Status::Stop) {
                  unset($reg[$key]);
                }
            }
        }


        return Command::SUCCESS;
    }
}

class SuspendData
{
    public readonly Status $status;

    public function __construct($status)
    {
        $this->status = $status;
    }
}

enum Status
{
    case Stop;
    case Running;
}
Copier après la connexion

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:learnku.com
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