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
-
Swoole4
PHP协程
est empruntée àGolang
, et je tiens à rendre hommage à l'équipe de développementGO
Se complètent bien. : Langage statique, rigoureux, puissant et performant, - : Langage dynamique, flexible, simple et facile à utiliser
PHP+Swoole
Golang
Golang
Cet article est basé sur lePHP+Swoole
et le versions
mots-clésSwoole-4.2.9
PHP-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
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. Array
socket
Apprentissage recommandé : "file
Tutoriel vidéo PHPIO
"
Concurrency Coroutine
L'utilisation de la fonction
coroutine pour exécution.
Exécution séquentiellego
function test1() { sleep(1); echo "b"; } function test2() { sleep(2); echo "c"; } test1(); test2();
go
Ré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,
etseront exécutés séquentiellement, et cela prendra
secondes à compléter.test1
Exécution simultanéetest2
3
L'utilisation de
et
exécutées simultanément.Swoole\Runtime::enableCoroutine(); go(function () { sleep(1); echo "b"; }); go(function () { sleep(2); echo "c"; });
go
test1
est utilisé pour faire passer les test2
, , ,secondes pour terminer l'exécution.SwooleRuntime::enableCoroutine()
,PHP
et d'autres fonctions fournies parstream
du blocage synchrone à la coroutine asynchronesleep
pdo
mysqli
Ré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:~$IO
Vous pouvez voir qu'il n'a fallu que
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 coroutine
max(t1, t2, t3, ...)
Avec le mot-clé
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
et Channel
: Swoole4
new chan
push
pop
: é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
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.com
1
Http
Coroutine chan
boucle deux fois sur le canal
- Coroutine
1
et coroutinepop
Aprè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
2
3
push
tâche retardée1
Dans la programmation en coroutine, vous devrez peut-être le faire. Lorsque la coroutine se termine, elle effectue automatiquement certaines tâches et nettoie.
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_function
Ré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$
defer
Conclusion 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. PHP
CSP