>  기사  >  백엔드 개발  >  Python의 코루틴에 대한 자세한 설명(예제 포함)

Python의 코루틴에 대한 자세한 설명(예제 포함)

不言
不言앞으로
2018-10-13 16:31:012932검색

이 글은 Python의 코루틴에 대한 자세한 설명을 제공합니다(예제 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

마이크로 스레드 및 파이버라고도 알려진 코루틴. 영어 이름 Coroutine
코루틴은 서브루틴처럼 보이지만 실행 중에 서브루틴 내부에서 중단되었다가 다른 서브루틴 실행으로 전환되었다가 적절한 시점에 다시 실행을 계속할 수 있습니다.

가장 큰 장점은 코루틴의 실행 효율성이 매우 높다는 것입니다. 서브루틴 전환은 스레드 전환이 아니라 프로그램 자체에 의해 제어되므로 스레드 전환에 따른 오버헤드가 없습니다. 멀티스레딩에 비해 스레드 수가 많을수록 코루틴의 성능 이점은 더욱 분명해집니다.
두 번째로 큰 장점은 스레드가 하나뿐이고 동시에 변수 작성 시 충돌이 없기 때문에 멀티 스레드 잠금 메커니즘이 필요하지 않다는 것입니다. 공유 리소스는 잠금 없이 코루틴에서 제어되며, 상태만 판단하면 되므로 멀티스레딩보다 실행 효율이 훨씬 높습니다.
코루틴은 스레드로 실행되기 때문에 멀티코어 CPU는 어떻게 사용하나요? 가장 간단한 방법은 다중 프로세스 + 코루틴으로, 다중 코어를 최대한 활용할 뿐만 아니라 코루틴의 높은 효율성을 최대한 활용하여 매우 높은 성능을 달성할 수 있습니다.

yield는 코루틴을 구현합니다

Python의 코루틴 지원은 여전히 ​​매우 제한적입니다. 생성기에 사용되는 Yield는 어느 정도 코루틴을 구현할 수 있습니다. 비록 지원이 완전하지는 않지만 이미 상당한 위력을 발휘할 수 있습니다.

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

Python의 코루틴에 대한 자세한 설명(예제 포함)

gevent 라이브러리는 코루틴을 구현합니다

Python은 Yield를 통해 코루틴에 대한 기본 지원을 제공하지만 완전하지는 않습니다. 타사 gevent는 Python에 대해 비교적 완전한 코루틴 지원을 제공합니다.

gevent는 greenlet을 통해 코루틴을 구현하는 타사 라이브러리입니다. 기본 아이디어는 다음과 같습니다.
greenlet이 네트워크 액세스와 같은 IO 작업을 만나면 자동으로 다른 greenlet으로 전환하고 IO 작업이 완료될 때까지 기다립니다. 그런 다음 적절한 시간에 다시 전환하여 실행을 계속합니다. IO 작업은 시간이 많이 걸리기 때문에 프로그램은 종종 대기 상태로 남아 있습니다. gevent가 자동으로 코루틴을 전환하면 IO를 기다리는 대신 Greenlet이 항상 실행되는 것이 보장됩니다.

전환은 IO 작업 중에 자동으로 완료되므로 gevent는 시작 시 Python과 함께 제공되는 일부 표준 라이브러리를 수정해야 합니다.

여러 코루틴에 의해 실행되는 작업에 IO 작업이나 대기가 없다고 가정하면 코루틴은 교대로 실행되는 대신 순차적으로 실행됩니다.
여러 코루틴에 의해 실행되는 작업에 IO 작업이나 대기가 있다고 가정하면 코루틴이 교대로 실행됩니다.

Python의 코루틴에 대한 자세한 설명(예제 포함)

#没有等待
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()

Python의 코루틴에 대한 자세한 설명(예제 포함)

코루틴과 스레드

코루틴과 스레드에 소요된 시간을 비교 실험해 보세요. 이는 유익하지 않습니다.

"""
#有等待
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()

Python의 코루틴에 대한 자세한 설명(예제 포함)

위 내용은 Python의 코루틴에 대한 자세한 설명(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제