Pour être honnête, je ne peux pas vraiment parler de "ce qu'est la programmation asynchrone". Cet article décrit ce que nous avons appris sur l'un des éléments de la programmation asynchrone: le multitâche collaboratif, l''async 'de Python et les boucles d'événements.
Le multitâche collaboratif est un élément central de la programmation asynchrone et ressemble à une idée.
Lorsqu'un ordinateur exécute le multitâche, il n'utilise pas le changement de contexte du système d'exploitation. Lorsque chaque processus entre en état de veille, le processus lui-même libère volontairement le contrôle. Donne le contrôle à de nombreux autres processus exécutés en même temps. (Comparable à la signification de ** coopérative **) Le contrôle fait ici référence à la suspension et à la reprise d'un processus, ainsi qu'à l'allocation et à la libération de ressources.
Il semble que tous les processus doivent être coordonnés afin d'effectuer le multitâche en douceur.
Où faites-vous le multitâche collaboratif? Plutôt que de coordonner plusieurs processus ou threads ** Tout le multitâche est exécuté dans un processus ou un thread. ** **
Qui contrôle la tâche? Le contrôle de plusieurs tâches est limité à une seule fonction, qui gère la coordination des tâches.
Dans le multitâche collaboratif, le problème le plus important est de savoir quand libérer le contrôle **. Le moment de la publication est similaire au comportement des threads. Où? ⇒ De nombreuses applications asynchrones donnent le contrôle à la boucle d'événements ou au planificateur au moment de l'instruction d'E / S. Relâchez le contrôle en attendant le traitement des E / S.
Quelle est la différence? ⇒ ** Thread ** est dû à un thread au niveau du système, ** OS peut interrompre le thread en cours d'exécution à tout moment ** et passer le contrôle à d'autres threads. En ** programmation asynchrone **, ** les tâches ne peuvent pas être interrompues par des boucles d'événements. ** (multitâche non préemptif)
Python s'exécute sur le système d'exploitation, en concurrence pour d'autres processus et ressources. En d'autres termes, le système d'exploitation contrôle tous les processus. Dans le cas d'une application asynchrone, le traitement est interrompu par une interruption du planificateur, mais lorsque le contrôle est retourné, il reprend à partir de l'endroit où il a été interrompu. Ce n'est pas toujours le cas avec le multithreading et le multiprocessing. Aussi, En ** multi-processus et threads **, la tâche à redémarrer est déterminée par le planificateur du système d'exploitation **. En ** programmation asynchrone **, l'application ** décide de la tâche à reprendre.
et ʻawait
en Python et ʻawait
ʻAsync est utilisé avant l'instruction
def pour définir un nouveau collout (tâche parallèle). L'exécution de la fonction collout est interrompue et reprise selon la situation définie. Même si la fonction définie par ʻasync
est appelée, la fonction n'est pas exécutée sur place et un ** objet collout ** est retourné.
Voici un exemple de mise en œuvre.
>>> async def asyc_hello():
... print("Hello")
...
>>> asyc_hello()
<coroutine object asyc_hello at 0x000001D3D021C748>
Vous pouvez voir que ʻasyc_hello () retourne un objet collout au lieu de la valeur de sortie standard de
print ("Hello") `.
Alors, qu'est-ce qu'un objet collout? Comment dois-je gérer cela? Je vais expliquer ce domaine en gros.
Vous devez créer quelque chose pour exécuter un objet collout. C'est une ** boucle d'événement **.
Vous trouverez ci-dessous le code qui a créé la boucle d'événements et exécuté l'objet collout.
>>> import asyncio
>>> async def asyncio_hello():
... print("Bonjour")
...
>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(asyncio_hello())
Bonjour
>>> loop.close()
Créez une boucle d'événements avec ʻasyncio.get_event_loop () L'objet collout est exécuté par
run_until_complete (asyncio_hello ())`. Ensuite, j'expliquerai les bases de ce qu'est la boucle d'événements.
Cet article n'explique pas les termes liés aux boucles d'événements. Au lieu d'expliquer la file d'attente d'événements, le répartiteur d'événements, le gestionnaire d'événements, la fonction de rappel, etc., je me suis concentré sur ce que fait le mécanisme de boucle d'événements et j'ai exprimé ce que j'ai appris dans la figure. Ci-dessous la figure. Pour plus de commodité, nous avons changé l'expression «événement» en «demande». (Pour plus de commodité, il est plus facile d'en avoir une image personnellement)
Revenons à la gestion des objets colloutés. L'objet collout sera celui qui est exécuté dans la boucle d'événements. De plus, il est mis en file d'attente dans la boucle d'événements et l'objet collout ne fait rien jusqu'à ce que son tour arrive. Le code source suivant est le code qui prépare un seul collout simple et exécute la boucle d'événements.
asyncprint.py
import asyncio
async def print_numeber(number):
print(number)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(
asyncio.wait([
print_numeber(number)
for number in range(10)
])
)
loop.close()
$ python src/asyncpritn.py
2
4
8
6
9
5
1
3
7
0
C'est le flux de base du code ci-dessus.
Ensuite, c'est un exemple lorsque le mot réservé ʻawaitest ajouté à ʻasyncio.wait ()
.
corowait.py
import time
import random
import asyncio
async def waiter(name):
for _ in range(4):
time_to_sleep = random.randint(1,3)/4
time.sleep(time_to_sleep)
print(
"{}Est{}Attendu une seconde"
"".format(name, time_to_sleep)
)
async def main():
await asyncio.wait([waiter("foo"), waiter("bar")])
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
$time python corowait.py
toto vaut 0.Attendu 5 secondes
toto vaut 0.Attendu 25 secondes
toto vaut 0.Attendu 75 secondes
toto vaut 0.Attendu 25 secondes
la barre est 0.Attendu 25 secondes
la barre est 0.Attendu 75 secondes
la barre est 0.Attendu 75 secondes
la barre est 0.Attendu 25 secondes
real 0m4.416s
user 0m0.130s sys 0m0.013s
ʻAwaitattend que le collout retourne l'exécution, puis libère le contrôle et le passe à la boucle d'événements jusqu'à ce qu'il finisse de s'exécuter. Ici, le traitement est bloqué par la fonction
time.sleep (). Par conséquent, cela devient un processus synchrone et les processus sont exécutés dans l'ordre. En Python, il existe une fonction ʻasycio.sleep ()
pour changer le traitement bloquant en traitement non bloquant et en traitement asynchrone. En utilisant cela, il est possible d'exécuter un traitement asynchrone. Voici un exemple de code.
cowait_improved.py
import time
import random
import asyncio
async def waiter(name):
for _ in range(4):
time_to_sleep = random.randint(1,3)/4
await asyncio.sleep(time_to_sleep)
print(
"{}Est{}Attendu une seconde"
"".format(name, time_to_sleep)
)
async def main():
await asyncio.wait([waiter("foo"), waiter("bar")])
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
$time python corowait_improved.py
toto vaut 0.Attendu 25 secondes
la barre est 0.Attendu 75 secondes
toto vaut 0.Attendu 75 secondes
la barre est 0.Attendu 75 secondes
toto vaut 0.Attendu 75 secondes
la barre est 0.Attendu 25 secondes
toto vaut 0.Attendu 25 secondes
la barre est 0.Attendu 25 secondes
real 0m2.442s
user 0m0.161s sys 0m0.017s
Les fonctions «foo» et «bar» sont exécutées en alternance, améliorant la vitesse de traitement. Cela signifie que le collout a relâché le contrôle en coopération.
https://www.atmarkit.co.jp/ait/articles/1103/23/news101_2.html Introduction à Python3 Expert Python Programming Revised 2nd Edition
Recommended Posts