Maison  >  Article  >  développement back-end  >  Explication détaillée des coroutines PHP : Go + Chan + Defer

Explication détaillée des coroutines PHP : Go + Chan + Defer

藏色散人
藏色散人avant
2021-06-27 17:01:184142parcourir

Swoole4 fournit un puissant modèle de programmation de coroutine PHP pour le langage CSP. La couche inférieure fournit des mots-clés 3, qui peuvent facilement implémenter diverses fonctions. La syntaxe

fournie par
  • Swoole4PHP协程 est empruntée à Golang, et je tiens à rendre hommage à l'équipe de développement GO Se complètent bien.
  • : Langage statique, rigoureux, puissant et performant,
  • : Langage dynamique, flexible, simple et facile à utiliserPHP+SwooleGolangGolangCet article est basé sur le PHP+Swoole et le
  • versions
mots-clés Swoole-4.2.9PHP-7.2.9

 : Créer une coroutine

  •  : Créer un canal go
  •  : Tâche de retard , exécuté à la sortie de la coroutine, Premier entré, dernier sorti chan
  • L'implémentation sous-jacente de cette defer fonction est constituée de toutes les
  • opérations de mémoire
sans aucune

consommation de ressources. Comme les 3 sont très bon marché. Vous pouvez l'utiliser directement si nécessaire. Ceci est différent des opérations et IO, qui nécessitent de demander des ports et des descripteurs de fichiers à partir du système d'exploitation, et la lecture et l'écriture peuvent provoquer un blocage PHP en attente. ArraysocketApprentissage recommandé : "fileTutoriel vidéo PHPIO"

Concurrency Coroutine
L'utilisation de la fonction

peut exécuter une fonction simultanément et l'implémenter . Pendant le processus de programmation, si un certain élément de logique peut être exécuté simultanément, il peut être placé dans une

coroutine pour exécution.

Exécution séquentiellego

function test1() 
{
    sleep(1);
    echo "b";
}
    
function test2() 
{
    sleep(2);
    echo "c";
}

test1();
test2();
goRésultat de l'exécution :
htf@LAPTOP-0K15EFQI:~$ time php b1.php
bc
real    0m3.080s
user    0m0.016s
sys     0m0.063s
htf@LAPTOP-0K15EFQI:~$

Dans le code ci-dessus,

et

seront exécutés séquentiellement, et cela prendra

secondes à compléter.

test1Exécution simultanéetest23L'utilisation de

pour créer une coroutine peut rendre les deux fonctions

et

exécutées simultanément.

Swoole\Runtime::enableCoroutine();

go(function () 
{
    sleep(1);
    echo "b";
});
    
go(function () 
{
    sleep(2);
    echo "c";
});
gotest1 est utilisé pour faire passer les test2, ,
, SwooleRuntime::enableCoroutine(), PHP et d'autres fonctions fournies par stream du blocage synchrone à la coroutine asynchrone sleeppdomysqliRésultat de l'exécution : redis
bchtf@LAPTOP-0K15EFQI:~$ time php co.php
bc
real    0m2.076s
user    0m0.000s
sys     0m0.078s
htf@LAPTOP-0K15EFQI:~$
IOVous pouvez voir qu'il n'a fallu que
secondes pour terminer l'exécution.

Le temps d'exécution séquentielle est égal à la somme des temps d'exécution de toutes les tâches : 2

    Le temps d'exécution simultanée est égal au temps d'exécution maximum de toutes les tâches :
  • t1+t2+t3...
  • Communication coroutinemax(t1, t2, t3, ...)
  • Avec le mot-clé
, la programmation simultanée est beaucoup plus simple. En même temps, cela pose de nouveaux problèmes. S'il y a des

coroutines s'exécutant simultanément, une autre coroutine doit s'appuyer sur les résultats d'exécution de ces deux coroutines. Et si ce problème était résolu ?

La réponse est d'utiliser un canal (go). Vous pouvez créer un canal en utilisant 2 dans la coroutine

. Un canal peut être compris comme une file d’attente avec sa propre planification de coroutines. Il dispose de deux interfaces

et Channel : Swoole4new chanpushpop : écrivez du contenu sur la chaîne, si elle est pleine, elle entrera en état d'attente et reprendra automatiquement lorsqu'il y aura de la place

  •  : Lisez le contenu de la chaîne. S'il est vide, il entrera en état d'attente et reprendra automatiquement lorsqu'il y aura des données push
  • L'utilisation des chaînes peut facilement être réalisée pop Gestion de la concurrence
  • .
$chan = new chan(2);

# 协程1
go (function () use ($chan) {
    $result = [];
    for ($i = 0; $i < 2; $i++)
    {
        $result += $chan->pop();
    }
    var_dump($result);
});

# 协程2
go(function () use ($chan) {
   $cli = new Swoole\Coroutine\Http\Client('www.qq.com', 80);
       $cli->set(['timeout' => 10]);
       $cli->setHeaders([
       'Host' => "www.qq.com",
       "User-Agent" => 'Chrome/49.0.2587.3',
       'Accept' => 'text/html,application/xhtml+xml,application/xml',
       'Accept-Encoding' => 'gzip',
   ]);
   $ret = $cli->get('/');
   // $cli->body 响应内容过大,这里用 Http 状态码作为测试
   $chan->push(['www.qq.com' => $cli->statusCode]);
});

# 协程3
go(function () use ($chan) {
   $cli = new Swoole\Coroutine\Http\Client('www.163.com', 80);
   $cli->set(['timeout' => 10]);
   $cli->setHeaders([
       'Host' => "www.163.com",
       "User-Agent" => 'Chrome/49.0.2587.3',
       'Accept' => 'text/html,application/xhtml+xml,application/xml',
       'Accept-Encoding' => 'gzip',
   ]);
   $ret = $cli->get('/');
   // $cli->body 响应内容过大,这里用 Http 状态码作为测试
   $chan->push(['www.163.com' => $cli->statusCode]);
});

résultat de l'exécution :

htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php co2.php
array(2) {
  ["www.qq.com"]=>
  int(302)
  ["www.163.com"]=>
  int(200)
}

real    0m0.268s
user    0m0.016s
sys     0m0.109s
htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$
utilise

pour créer

coroutines

et coroutine

requête go et 3 page d'accueil. La coroutine 2 doit obtenir le résultat demandé par 3. qq.com est utilisé ici pour implémenter la gestion de la concurrence. 163.com1HttpCoroutine chan boucle deux fois sur le canal

, car la file d'attente est vide, elle entrera dans l'état d'attente
  • Coroutine 1 et coroutine popAprès l'exécution est terminée,
  • les données seront générées. La coroutine
  • obtient le résultat et continue d'exécuter 23push tâche retardée 1
  • Dans la programmation en coroutine, vous devrez peut-être le faire. Lorsque la coroutine se termine, elle effectue automatiquement certaines tâches et nettoie.
similaire à

peut être implémenté en utilisant

dans

. PHP

Swoole\Runtime::enableCoroutine();

go(function () {
    echo "a";
    defer(function () {
        echo "~a";
    });
    echo "b";
    defer(function () {
        echo "~b";
    });
    sleep(1);
    echo "c";
});
register_shutdown_functionRésultats d'exécution : Swoole4
htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php defer.php
abc~b~a
real    0m1.068s
user    0m0.016s
sys     0m0.047s
htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$
deferConclusion

Le

fourni par

apporte un nouveau

modèle de programmation simultanée à Swoole4. L'utilisation flexible des diverses fonctionnalités fournies par Go + Chan + Defer peut résoudre la conception et le développement de diverses fonctions complexes au travail. PHPCSP

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