Python은 yield 코루틴을 사용하여 생산자 소비자 문제를 구현합니다.

목차

코루틴

공식 웹 사이트 정의

대중적인 이해

코루틴의 장점

파이썬 코루틴을 사용하는 방법

코드 예제

연산 결과

수율은 생산자 소비자를 구현합니다.

소비자 정의

프로듀서 정의

프로그램 실행 출력

분석하다


코루틴

공식 웹 사이트 정의

        코루틴은 사용자 모드의 경량 스레드이며 코루틴의 스케줄링은 사용자가 완전히 제어합니다. 코루틴에는 자체 레지스터 컨텍스트와 스택이 있습니다. 코루틴 스케줄이 전환되면 레지스터 컨텍스트와 스택은 다른 곳에 저장되고, 다시 전환되면 이전에 저장된 레지스터 컨텍스트와 스택이 복원되며 기본적으로 스택의 직접 작동을 위한 커널 전환 오버헤드가 없으며 전역 변수는 잠금 없이 액세스할 수 있으므로 컨텍스트 전환이 매우 빠릅니다.

대중적인 이해

        코루틴은 마이크로 스레드라고도 합니다.코루틴의 완성은 주로 yield 키워드에 따라 달라집니다.코루틴 실행 중에 서브루틴 내부에서 중단되고 현재 실행 중인 컨텍스트를 일시 중단한 다음 다른 서브루틴을 실행하도록 전환할 수 있습니다. . 돌아와서 적절할 때 실행합니다.

코루틴의 장점

        파이썬에서 동시성을 달성하는 방법은 여러 가지가 있는데, 멀티 프로세스 동시성은 멀티 코어 리소스를 진정으로 활용할 수 있는 반면, 멀티 스레드 동시성은 프로세스 내에서 리소스 공유를 실현합니다. 실제로 의사 멀티 스레딩입니다.
        컴퓨팅 집약적인 프로그램의 경우 멀티 프로세스 동시성을 사용하여 멀티 코어 리소스를 최대한 활용해야 합니다. IO 집약적인 프로그램에서는 멀티 코어의 이점이 명확하지 않습니다. 대부분의 경우에도 시간 중 IO 차단 상태에 있으면 여러 프로세스의 전환 소비로 인해 프로그램 효율성이 더욱 낮아지고
        IO 집약적인 작업을 동시에 처리해야 하는 경우 코루틴(Coroutine)을 사용해야 합니다. 코루틴은 시스템 수준 스케줄링이 아니라 사용자 수준 스케줄링으로 시스템 호출의 오버헤드를 방지합니다. 코루틴은 궁극적으로 직렬로 작동하지만 매우 많은 양의 동시성을 달성할 수 있습니다. 다중 프로세스 + 코루틴을 통해 다중 코어 컴퓨팅과 요청 대기가 효과적으로 균형을 이룰 수 있습니다.

파이썬 코루틴을 사용하는 방법

1. yield 키워드가 있는 함수는 자동으로 생성기가 됩니다.

2. 제너레이터는 호출 즉시 실행되지 않습니다.

3. 제너레이터의 경우 next(generator) 함수가 호출되면 제너레이터 yield 이후의 표현식 값을 얻습니다.

4. 제너레이터 실행이 완료되면 다음 함수를 다시 호출하면 제너레이터에서 StopIteration 예외가 발생합니다.

코드 예제

yield를 사용하는 foo() 메서드 정의

def foo():
    while True:
        print("======这是yield之前前前前====")
        x = yield
        print("x当前值:{0}".format(x))
        print("======这是yield之后后后后====")

next() 및 send() 사용

if __name__ == '__main__':
    g = foo()
    # 第一次调用next的时候,程序从函数最开始处运行,执行到yield处,停在该处
    next(g)
    print("\n=====================下 一 个====================\n")
    next(g)
    print("\n=====================下 一 个====================\n")
    # send将参数赋给yield的返回值,然后该返回值赋给了变量x
    # 继续程序的执行,直到下一次遇到yield停下来
    g.send(1)
    # next就相当于send(None)
    print("\n=====================下 一 个====================\n")
    g.send(None)

연산 결과

        실제로 yield 키워드 위치에서 프로그램이 아래쪽으로 실행되는 것을 중지함과 동시에 현재 실행 위치를 기억하고 다음 번에 이 위치에서 끝까지 또는 다시 yield를 만날 때까지 계속해서 역방향으로 실행되는 것을 확인할 수 있습니다.

        우리는 코루틴에 하나의 스레드만 있고 동시에 변수를 쓰는 충돌이 없기 때문에 전체 프로그램 프로세스에서 잠금이 사용되지 않는다는 것을 발견했습니다. 따라서 코루틴에서 공유 리소스를 제어하기 위해 잠금을 할 필요가 없습니다. , 상태를 판단하기 위해서만.

수율은 생산자 소비자를 구현합니다.

소비자 정의

def cousume():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        print("消费者说:消费者消费了第{0}个".format(n))
        time.sleep(1)
        r = '用了'

프로듀서 정의

def produce(c):
    next(c)
    n = 0
    while n < 3:
        n += 1
        print("生产者说:生产者生产了第{0}个:".format(n))
        r = c.send(n)
        print("生产者说:消费者反馈-- {0}".format(r))
    c.close()

프로그램 실행 출력

if __name__ == '__main__':
    c = cousume()
    produce(c)
    print("结束")

분석하다

  1. 먼저 소비 함수를 호출합니다. 소비 함수의 반환은 생산 함수로 전달되는 생성기입니다.
  2. 생성 함수에서 next(c)를 호출하여 생성기를 시작합니다.
  3. n = n + 1을 계산하여 데이터를 생성하고, 데이터가 생성되면 c.send(n)을 호출하여 실행 소비로 전환합니다.
  4. 소비 함수에서 데이터를 가져온 후 n에 할당하고 yield 이후 명령문을 계속 실행합니다.
  5. 소비 함수는 소비된 데이터를 인쇄하고 반환 값 r을 설정하고 루프의 시작 부분으로 돌아가 결과를 yield를 통해 다시 전달합니다.
  6. 생산은 소비가 반환한 값을 가져오고 계속해서 다음 데이터를 생산합니다.
  7. 데이터 생성이 완료되면 루프가 종료되고 c.close()를 통해 소비가 종료되어 전체 프로세스가 종료됩니다.

    알아채다

        생산 및 소비 기능은 하나의 스레드에서 실행되며 send 메서드와 yield를 호출하여 서로 전환합니다.

서브루틴은 코루틴의 특별한 경우입니다. — 도널드 크누스

댓글 영역에서 좋아요, 수집 및 댓글을 환영하고 출처를 표시하기 위해 전재하십시오.

おすすめ

転載: blog.csdn.net/qq_52213943/article/details/127750741