Maison  >  Article  >  développement back-end  >  Explication détaillée des coroutines en Python

Explication détaillée des coroutines en Python

王林
王林original
2023-06-10 11:37:464440parcourir

Python est un langage de programmation populaire largement utilisé en raison de sa simplicité, de sa facilité d'apprentissage et de sa large gamme d'applications. Parmi eux, la coroutine est un concept très important en Python et l'un des fondements de la programmation asynchrone des E/S en Python. Cet article fournira une explication détaillée des coroutines en Python.

1. Qu'est-ce qu'une coroutine ? La coroutine est un thread léger en mode utilisateur, qui est plus portable que les threads du système d'exploitation. Il est implémenté par le programmeur dans le programme, il n'est donc pas nécessaire de changer de contexte. Le changement de coroutine est effectué par le programme lui-même sans intervention externe. Il peut également réduire la création de threads et utiliser les ressources du processeur plus efficacement.

Caractéristiques des coroutines :

peut s'exécuter simultanément dans le même thread, et la surcharge de commutation est très faible, elle prend donc en charge une concurrence élevée.
  1. Le statut de la coroutine est géré par le programmeur lui-même, ce qui est plus léger que les threads.
  2. 2. Implémentation des coroutines

Il existe trois façons d'implémenter des coroutines en Python : générateur, async/await et combiné avec gevent. Ci-dessous, nous les présentons un par un.

Générateur
  1. Le générateur en Python lui-même a la fonction de sauvegarde et de restauration d'état, ce qui est très approprié pour l'implémentation de coroutines. La plus grande fonctionnalité de la coroutine du générateur est d'utiliser l'instruction rendement pour suspendre la fonction et enregistrer l'état de la fonction.

Voici un exemple de coroutine :

def simple_coroutine():
    print('-> coroutine started')
    x = yield
    print('-> coroutine received:', x)

# 调用协程
my_coroutine = simple_coroutine()
print(my_coroutine)  # <generator object simple_coroutine at 0x7f6b25c43eb0>

# 先启动协程,让协程处于暂停状态。
next(my_coroutine)  # -> coroutine started

# 发送消息给协程,它会恢复执行,并打印出消息
my_coroutine.send('hello world')  # -> coroutine received: hello world

Dans cet exemple, la fonction simple_coroutine contient une expression de rendement, qui est le signe d'une coroutine génératrice. Lorsque la fonction est appelée, elle renvoie un objet générateur. Le programme avance le générateur jusqu'à la première instruction rendement en appelant la méthode next() et imprime le message "-> coroutine démarrée". Ensuite, nous avons envoyé un message "hello world" au générateur, qui a été capturé dans la variable x et imprimé "-> coroutine reçue : hello world".

async/await
  1. Après Python 3.5, Python fournit un support natif pour la syntaxe coroutine async/await. Il offre une syntaxe plus claire et une meilleure lisibilité.

Voici un exemple de async/await :

import asyncio

async def countdown(n):
    while n > 0:
        print(f'T-minus {n}')
        await asyncio.sleep(1.0)
        n -= 1

asyncio.run(countdown(3))

Dans cet exemple, async/await nous permet d'utiliser le mot-clé async dans la fonction pour définir la coroutine et d'utiliser wait pour suspendre la coroutine. Bien sûr, pour utiliser la syntaxe async/wait, nous devons utiliser la bibliothèque asyncio.

Utiliser avec gevent
  1. gevent est une bibliothèque réseau Python basée sur des coroutines. Elle fournit un modèle de programmation basé sur le rendement qui permet aux programmeurs d'écrire du code asynchrone et non bloquant, facile à écrire et à tester. Pour utiliser gevent, nous devons d'abord l'installer via pip.

Voici un exemple utilisant gevent :

import gevent

def task(pid):
    """
    函数中的sleep模拟阻塞一段时间,通过gevent中的异步框架进行并发。
    """
    gevent.sleep(0.5)
    print(f'Task {pid} done')

def synchronous():
    """
    任务同步执行
    """
    for i in range(1, 10):
        task(i)

def asynchronous():
    """
    任务异步执行
    """
    threads = [gevent.spawn(task, i) for i in range(10)]
    gevent.joinall(threads)

print('Synchronous:')
synchronous()

print('Asynchronous:')
asynchronous()

Dans cet exemple, nous utilisons le framework gevent pour implémenter des coroutines asynchrones. A travers cet exemple, on voit bien que lors d'une exécution asynchrone, les tâches sont exécutées en alternance, profitant des caractéristiques asynchrones des coroutines. Lors d'une exécution synchrone, nous pouvons voir que les tâches sont exécutées une par une.

3. Avantages et inconvénients des coroutines

Avantages :

Les coroutines sont monothread par défaut, ce qui évite la surcharge causée par la commutation multithread et améliore la vitesse d'exécution du programme.
  1. Les coroutines peuvent éviter les problèmes GIL (Global Interpreter Lock) multi-processus et améliorer l'efficacité du programme.
  2. Les coroutines peuvent être créées à l'infini, mais le nombre de threads et de processus est limité, mais ouvrir trop de coroutines entraînera également des problèmes de performances.
  3. Inconvénients :

Les coroutines sont spéciales et nécessitent que les programmeurs contrôlent manuellement l'état d'exécution du programme. Sa complexité est relativement élevée et nécessite plus d'efforts.
  1. Le code de la coroutine lui-même n'a pas de mécanisme de gestion des erreurs, ce qui rend plus difficile la gestion des exceptions et le débogage du code.
  2. 4. Résumé

Cet article présente en détail le concept, les méthodes d'implémentation ainsi que les avantages et les inconvénients des coroutines en Python. Les coroutines sont un concept très important en Python et l'un des fondements de la programmation IO asynchrone. Grâce aux coroutines, nous pouvons exécuter des activités simultanément dans le même thread, améliorer l'efficacité de l'exécution des programmes, éviter de nombreuses surcharges de changement de contexte et économiser considérablement les ressources système. Cependant, les coroutines présentent également certaines lacunes, telles que des exigences élevées en matière de compétences en programmation des programmeurs et des mécanismes de gestion des erreurs imparfaits. Ces problèmes nécessitent que les programmeurs y prêtent attention lorsqu'ils utilisent des coroutines.

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