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.
L'environnement d'exploitation de ce tutoriel : système Windows 10, version Swoole 4, ordinateur DELL G3
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)
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!