Le code suivant sort comme suit:
1 sec delay, print "1",
1 sec delay, print "2",
1 sec delay, print "1",
1 sec delay, print "2"
Comment peut-il être modifié pour fonctionner comme ceci:
1 sec delay, print "1", print "1",
1 sec delay, print "2", print "2"
Je voudrais qu'il s'exécute pour que les deux instances de la boucle for commencent à s'exécuter en même temps. À mesure que chaque instance s'exécute, elles rencontrent la première fonction () en même temps, puis la seconde fonction () en même temps, imprimant ainsi dans l'ordre mentionné ci-dessus.
Code:
import asyncio
async def first():
await asyncio.sleep(1)
return "1"
async def second():
await asyncio.sleep(1)
return "2"
async def main():
for i in range(2):
result = await first()
print(result)
result2 = await second()
print(result2)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
En regardant la sortie souhaitée, il semble que le but est de laisser l'itération individuelle telle qu'elle est - c'est-à-dire d'exécuter first
et second
séquentiellement - mais d'exécuter les deux itérations de boucle en parallèle.
En supposant que vous souhaitiez seulement modifier main()
, cela pourrait être réalisé comme ceci:
async def main():
async def one_iteration():
result = await first()
print(result)
result2 = await second()
print(result2)
coros = [one_iteration() for _ in range(2)]
await asyncio.gather(*coros)
Au lieu d'itérer en séquence, ce qui précède crée une coroutine pour chaque tâche d'itération et utilise asyncio.gather
pour exécuter toutes les itérations en parallèle.
Notez que la simple création d'une coroutine ne démarre pas son exécution, donc un grand nombre de coros
ne bloquera pas la boucle d'événement.
Avec la bibliothèque aysncio, vous pouvez utiliser aysncio.gather ()
loop.run_until_complete(asyncio.gather(
first(),
second()
))
Cela peut être utile si vous envoyez également des requêtes HTTP en parallèle:
loop.run_until_complete(asyncio.gather(
request1(),
request2()
))
Pour exécuter les deux fonctions simultanément, vous pouvez utiliser gather
. Cependant, les résultats vous seront fournis dans l'ordre que vous leur fournissez. Ainsi, par exemple, si vous le faites
results = await asyncio.gather(first(), second())
Ensuite, vous récupérerez [the result of first(), the result of second()]
. Si vous voulez faire quelque chose chaque fois que chacun retourne, vous devez utiliser Tasks
explicitement et ajouter des rappels .