Maison  >  Article  >  cadre php  >  Quel est le principe de mise en œuvre de la coroutine swoole ?

Quel est le principe de mise en œuvre de la coroutine swoole ?

WBOY
WBOYoriginal
2022-02-14 17:42:416597parcourir

Dans swoole, le serveur Swoole reçoit des données et déclenche le rappel onReceive dans le processus de travail pour générer une coroutine. Swoole crée une coroutine correspondante pour chaque requête. Les sous-coroutines peuvent également être créées dans la coroutine. est monothread, donc une seule coroutine fonctionne en même temps.

Quel est le principe de mise en œuvre de la coroutine swoole ?

L'environnement d'exploitation de ce tutoriel : système Windows 10, version Swoole 4, ordinateur DELL G3

Quel est le principe de mise en œuvre de la coroutine swoole

Qu'est-ce qu'un processus ?

Un processus est l'instance de démarrage d'une application. Ressources de fichiers indépendantes, ressources de données et espace mémoire.

Qu'est-ce qu'un fil de discussion ?

Les threads appartiennent aux processus et sont les exécuteurs des programmes. Un processus contient au moins un thread principal et peut également avoir plusieurs threads enfants. Les threads ont deux stratégies de planification, l’une est la planification en temps partagé et l’autre est la planification préemptive.

Qu'est-ce qu'une coroutine ?

Les coroutines sont des threads légers, les coroutines appartiennent également aux threads et les coroutines sont exécutées dans les threads. La planification des coroutines est modifiée manuellement par l'utilisateur, elle est donc également appelée thread de l'espace utilisateur. La création, la commutation, la suspension et la destruction de coroutines sont toutes des opérations mémoire et la consommation est très faible. La stratégie de planification des coroutines est la suivante : planification collaborative.

Le principe de la coroutine Swoole

Swoole4 est monothread et multi-processus, et il n'y aura qu'une seule coroutine exécutée dans le même processus en même temps.

Le serveur Swoole reçoit des données et déclenche le rappel onReceive dans le processus de travail pour générer un Ctrip. Swoole crée un Ctrip correspondant pour chaque requête. Des sous-coroutines peuvent également être créées dans des coroutines.

L'implémentation sous-jacente de la coroutine est monothread, il n'y a donc qu'une seule coroutine fonctionnant en même temps, et l'exécution de la coroutine est en série.

Ainsi, lorsque le multitâche et le multi-coroutine sont exécutés, lorsqu'une coroutine est en cours d'exécution, les autres coroutines cesseront de fonctionner. La coroutine actuelle se bloquera lors de l'exécution d'opérations d'E/S bloquantes et le planificateur sous-jacent entrera dans la boucle d'événements. Lorsqu'un événement d'achèvement d'E/S se produit, le planificateur sous-jacent reprend l'exécution de la coroutine correspondant à l'événement. . Par conséquent, les coroutines n'ont pas de consommation de temps d'E/S et sont très adaptées aux scénarios d'E/S à haute concurrence. (Comme le montre l'image ci-dessous)

Quel est le principe de mise en œuvre de la coroutine swoole ?

Processus d'exécution de la coroutine de Swoole

  • La coroutine n'a pas d'E/S et attend l'exécution normale du code PHP, et aucun commutateur de flux d'exécution ne se produit

  • Les rencontres de la coroutine IO et attend un contrôle immédiat Une fois l'IO terminé, le flux d'exécution revient au point où la coroutine d'origine a été découpée

  • Les coroutines et les coroutines parallèles sont exécutées en séquence, selon la même logique que la précédente

  • Processus d'exécution imbriqué de la coroutine de l'extérieur vers l'intérieur La couche entre jusqu'à ce que l'IO se produise, puis passe à la coroutine externe La coroutine parent n'attendra pas la fin de la coroutine enfant

La séquence d'exécution de la coroutine

.

Jetons d'abord un coup d'œil à l'exemple de base :

go(function () {
    echo "hello go1 \n";});echo "hello main \n";go(function () {
    echo "hello go2 \n";});

go () est l'abréviation de Co::create(), qui est utilisée pour créer une coroutine, acceptant le rappel comme paramètre. Le code dans le rappel sera exécuté dans. cette nouvelle coroutine.

Remarque : SwooleCoroutine peut être abrégé en Co

Le résultat de l'exécution du code ci-dessus :

root@b98940b00a9b /v/w/c/p/swoole# php co.phphello go1
hello main
hello go2

Le résultat de l'exécution ne semble pas différent de l'ordre dans lequel nous écrivons habituellement le code Le processus d'exécution réel :

  • Exécutez ce code, le système démarre un nouveau processus

  • rencontre go( ), une coroutine est générée dans le processus en cours, heelo go1 est sorti dans la coroutine, la coroutine se termine

  • Le processus continue pour exécuter le code, hello main

  • est sorti, et une autre coroutine est générée, et heelo go2 est sorti dans la coroutine, la coroutine se ferme

Exécutez ce code et le système démarre un nouveau processus si vous. Si vous ne comprenez pas cette phrase, vous pouvez utiliser le code suivant :

// co.php<?phpsleep(100);

Exécutez et utilisez ps aux pour afficher les processus dans le système :

root@b98940b00a9b /v/w/c/p/swoole# php co.php &⏎
root@b98940b00a9b /v/w/c/p/swoole# ps auxPID   USER     TIME   COMMAND
    1 root       0:00 php -a   10 root       0:00 sh   19 root       0:01 fish  749 root       0:00 php co.php  760 root       0:00 ps aux

us Faisons un léger changement et expérimentons la planification des coroutines :

use Co;go(function () {
    Co::sleep(1); // 只新增了一行代码
    echo "hello go1 \n";});echo "hello main \n";go(function () {
    echo "hello go2 \n";});
\Co::sleep() 函数功能和 sleep() 差不多, 但是它模拟的是 IO等待(IO后面会细讲). 执行的结果如下:
root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
hello go2
hello go1

Pourquoi n'est-il pas exécuté séquentiellement ? Processus d'exécution réel :

  • Exécutez ce code, le système démarre un nouveau processus

  • rencontres go(), Une coroutine est générée dans le processus en cours

  • La coroutine rencontre un blocage d'IO (voici l'attente IO simulée par Co::sleep()), la coroutine abandonne le contrôle et entre dans la file d'attente de planification de la coroutine

  • processus Continuer l'exécution, sortie bonjour main

  • pour exécuter la coroutine suivante, sortie bonjour go2

  • La coroutine précédente est prête, continuez l'exécution, sortie bonjour go1

Jusqu'ici, vous pouvez déjà voir swoole Concernant la relation entre les coroutines et les processus, ainsi que la planification des coroutines, changeons le programme tout à l'heure :

go(function () {
    Co::sleep(1);
    echo "hello go1 \n";});echo "hello main \n";go(function () {
    Co::sleep(1);
    echo "hello go2 \n";});

Je pense que vous savez déjà à quoi ressemble le résultat :

root@b98940b00a9b /v/w/c/p/swoole# php co.phphello main
hello go1
hello go2

Apprentissage recommandé : Tutoriel swoole

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