Maison  >  Article  >  développement back-end  >  Explication détaillée des coroutines en python (avec exemples)

Explication détaillée des coroutines en python (avec exemples)

不言
不言avant
2018-10-13 16:31:012919parcourir

Cet article vous apporte une explication détaillée des coroutines en python (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Coroutines, également appelées micro-fils et fibres. Le nom anglais Coroutine
ressemble à un sous-programme, mais pendant l'exécution, il peut être interrompu à l'intérieur du sous-programme, puis passer à l'exécution d'autres sous-programmes, puis revenir pour continuer l'exécution au moment approprié.

Le plus grand avantage est l’efficacité d’exécution extrêmement élevée des coroutines. Étant donné que la commutation de sous-programmes n'est pas une commutation de thread, mais est contrôlée par le programme lui-même, il n'y a pas de surcharge de commutation de thread. Par rapport au multithread, plus le nombre de threads est grand, plus les avantages en termes de performances des coroutines sont évidents.
Le deuxième plus grand avantage est qu'il n'est pas nécessaire d'avoir un mécanisme de verrouillage multi-thread, car il n'y a qu'un seul thread et il n'y a pas de conflit dans l'écriture des variables en même temps. Les ressources partagées sont contrôlées dans la coroutine sans verrouillage. , et seul l'état doit être déterminé, donc exécuter L'efficacité est bien supérieure à celle du multi-threading.
Étant donné que la coroutine est exécutée par un thread, comment utiliser un processeur multicœur ? La méthode la plus simple est multi-processus + coroutine, qui non seulement utilise pleinement plusieurs cœurs, mais met également pleinement en valeur la haute efficacité de la coroutine et peut atteindre des performances extrêmement élevées.

yield implémente les coroutines

La prise en charge par Python des coroutines est encore très limitée. Yield utilisé dans les générateurs peut implémenter des coroutines dans une certaine mesure. Même si ce soutien n’est pas complet, il peut déjà exercer un pouvoir considérable.

import threading
import time
def producer(c):
    c.__next__()
    n=0
    while n c.send(n) --> n更新
        n = yield r
        if not n:
            break
        print('[消费者]正在调用第%s条数据' %(n))
        time.sleep(1)
        r = 'This is ok!'

if __name__=='__main__':
    print(threading.current_thread())   
    print(threading.active_count())     #查看当前进行的线程
    c = consumer()
    producer(c)     #函数中有yield, 返回值为生成器;
    print(threading.active_count()) #1

Explication détaillée des coroutines en python (avec exemples)

la bibliothèque gevent implémente les coroutines

Python fournit un support pour les coroutines via le support de base de rendement, mais pas complet. Le gevent tiers fournit une prise en charge relativement complète des coroutines pour Python.

gevent est une bibliothèque tierce qui implémente des coroutines via des greenlets. L'idée de base est la suivante :
Lorsqu'un greenlet rencontre une opération IO, comme l'accès au réseau, il passe automatiquement à d'autres greenlets et attend l'opération IO. est terminé, puis revenez en arrière pour continuer l'exécution le cas échéant. Étant donné que les opérations d'E/S prennent beaucoup de temps, le programme est souvent placé dans un état d'attente. Grâce au changement automatique de coroutines pour nous, il est garanti que les greenlets sont toujours en cours d'exécution au lieu d'attendre les E/S.

Étant donné que la commutation est automatiquement effectuée lors des opérations d'E/S, gevent doit modifier certaines des bibliothèques standard fournies avec Python. Ce processus est terminé via le patch singe au démarrage.

En supposant que les tâches exécutées par plusieurs coroutines n'ont pas d'opérations d'E/S ou d'attente, alors les coroutines s'exécutent séquentiellement au lieu d'alterner
Supposons que les tâches exécutées par plusieurs coroutines ont des opérations d'E/S ou en attente, alors les coroutines exécuter en alternance ; 🎜>Coroutines et threads

#没有等待
import gevent
from gevent import monkey
monkey.patch_all()
def job(n):
    for i in range(n):
        print(gevent.getcurrent(),i)

def mian():
    g1 = gevent.spawn(job,1)
    g2 = gevent.spawn(job,2)
    g3 = gevent.spawn(job,3)
    gevent.joinall([g1,g2,g3])
    print('协程执行任务结束...')

if __name__=="__main__":
    mian()

Une expérience comparative sur le temps passé par les coroutines et les threads n'est pas informative. Explication détaillée des coroutines en python (avec exemples)

"""
#有等待
import time
from gevent import  monkey
monkey.patch_all()

import  gevent
def job(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(1)

def main1():
    # 创建三个协程, 并让该协程执行job任务
    g1 = gevent.spawn(job, 2)
    g2 = gevent.spawn(job, 3)
    g3 = gevent.spawn(job, 2)
    # 等待所有的协程执行结束, 再执行主程序;
    gevent.joinall([g1, g2, g3])
    print("任务执行结束.....")

main1()

Explication détaillée des coroutines en python (avec exemples)

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer