코 루틴과 연속체와 발전기의 차이점은 무엇입니까?
답변
생성기부터 시작하겠습니다. 가장 간단한 경우입니다. @zvolkov가 언급했듯이 반환하지 않고 반복적으로 호출 할 수있는 함수 / 객체이지만 호출되면 값을 반환 (수율) 한 다음 실행을 일시 중단합니다. 그들이 다시 부름을 받으면, 그들은 마지막으로 실행을 중단 한 곳에서 시작하여 다시 일을합니다.
발전기는 본질적으로 컷 다운 (비대칭) 코 루틴입니다. 코 루틴과 생성기의 차이점은 코 루틴이 처음 호출 된 후 인자를 받아 들일 수 있지만 생성기는 할 수 없다는 것입니다.
코 루틴을 사용하는 곳의 사소한 예를 생각해내는 것은 약간 어렵지만 여기에 최선의 노력이 있습니다. 이 (구성된) 파이썬 코드를 예로 들어 보자.
def my_coroutine_body(*args):
while True:
# Do some funky stuff
*args = yield value_im_returning
# Do some more funky stuff
my_coro = make_coroutine(my_coroutine_body)
x = 0
while True:
# The coroutine does some funky stuff to x, and returns a new value.
x = my_coro(x)
print x
코 루틴이 사용되는 예는 렉서 및 파서입니다. 언어에 코 루틴이 없거나 어쨌든 에뮬레이션이 없으면 lexing 및 parsing 코드는 실제로 두 가지 별도의 우려 사항이더라도 함께 혼합해야합니다. 그러나 코 루틴을 사용하면 렉싱 및 구문 분석 코드를 분리 할 수 있습니다.
(저는 대칭 코 루틴과 비대칭 코 루틴의 차이점을 해결하려고합니다. 그것들이 동등하고 다른 것으로 변환 할 수 있으며, 비대칭 코 루틴 (발전기와 가장 유사한 것)은 파이썬에서 비대칭 코 루틴을 구현하는 방법을 간략히 설명했습니다.)
연속은 실제로 아주 단순한 짐승입니다. 그것들은 모두 프로그램의 다른 지점을 나타내는 함수이며, 호출하면 함수가 나타내는 지점으로 실행이 자동으로 전환됩니다. 당신은 그것을 깨닫지 않고 매일 매우 제한된 버전을 사용합니다. 예를 들어 예외는 일종의 인사이드 아웃 연속으로 생각할 수 있습니다. 계속해서 파이썬 기반의 의사 코드 예제를 드리겠습니다.
파이썬에이라는 callcc()
함수가 있고이 함수에는 두 개의 인수가 있는데, 첫 번째는 함수이고 두 번째는 호출 할 인수 목록입니다. 해당 함수에 대한 유일한 제한은 마지막 인수가 함수 (현재의 연속 임)가 될 것입니다.
def foo(x, y, cc):
cc(max(x, y))
biggest = callcc(foo, [23, 42])
print biggest
무엇 일어날 것은 즉 callcc()
에서 전화를 켜 것이 foo()
현재 계속 (과 cc
), 즉, 프로그램의 시점에 참조하는 callcc()
불렸다. foo()
현재 연속을 호출 할 때 현재 연속을 호출하는 callcc()
값으로 반환하도록 지시 하는 것과 본질적으로 동일하며 , 그렇게하면 스택을 현재 연속이 작성된 위치 (예 : 호출 한 시점)로 롤백합니다. callcc()
.
이 모든 결과는 가상의 파이썬 변형이 인쇄 될 것 '42'
입니다.
나는 그것이 도움이되기를 희망하며, 내 설명이 상당히 개선 될 수 있다고 확신합니다!
답변
코 루틴은 교대로 작업을 수행 한 다음 그룹의 다른 코 루틴을 제어하기 위해 일시 중지하는 몇 가지 절차 중 하나입니다.
계속은 일부 프로 시저로 전달되는 “함수를 가리키는 포인터”로, 해당 프로 시저가 완료 될 때 실행됩니다 ( “계속”).
Generator (.NET)는 값을 내뱉고 메소드의 “일시 정지”한 다음 다음 값을 요청할 때 같은 지점에서 진행할 수있는 언어 구성입니다.
답변
최신 버전의 Python에서는을 사용하여 Generators에 값을 보내서 generator.send()
Python Generators를 효과적으로 코 루틴으로 만들 수 있습니다.
python Generator와 greenlet과 같은 다른 생성기의 주요 차이점은 python yield value
에서는 호출자에게만 되돌릴 수 있다는 것입니다 . Greenlet에있는 동안 target.switch(value)
특정 대상 코 루틴으로 이동하여 target
계속 실행 되는 값을 산출 할 수 있습니다.