코 루틴이란?


204

코 루틴이란? 그것들은 동시성과 어떤 관련이 있습니까?


2
동시 코드가 반드시 "병렬"로 실행될 필요는 없습니다 (새로운 용어를 소개하지는 마십시오).
lucid_dreamer

2
Linux, BSD 및 Windows에 대한 select / poll / eplll / kqueue / iocp / Win GUI 메시지를 지원하는 표준 C로 코 루틴 라이브러리를 작성했습니다. github.com/acl-dev/libfiber 의 오픈 소스 프로젝트입니다 . 조언이 잘 될 것입니다.
ShuXin Zheng

더 흥미로운 정보는 여기에 있습니다 : stackoverflow.com/q/16951904/14357
지출 자

이 시대에 질문을 받으면이 질문이 다운 투표 될 것이라고 상상할 수 있습니다. 왜 이전과 비교했을 때 커뮤니티 인식의 차이가 그렇게 큰지 잘 모르겠습니까?
tnkh

코 루틴은 수익에 도달하기 전에 실행을 중지 할 수있는 기능이며, 간접적으로 몇 시간 동안 다른 코 루틴으로 제어를 전달할 수 있습니다.
hassanzadeh.sd

답변:


138

코 루틴과 동시성은 대체로 직교합니다. 코 루틴은 유량 제어가 복귀하지 않고 두 개의 서로 다른 루틴 사이에서 협력 적으로 통과되는 일반적인 제어 구조입니다.

파이썬의 'yield'문장이 좋은 예입니다. 코 루틴을 만듭니다. '수율'이 발생하면 기능의 현재 상태가 저장되고 제어는 호출 기능으로 돌아갑니다. 그러면 호출 함수는 실행을 양보 함수로 다시 전송할 수 있으며 상태는 '수율'이 발생한 지점으로 복원되고 실행이 계속됩니다.


19
함수를 직접 호출하는 것과이 함수를이 코 루틴으로 감싸서 코 루틴에서 생성하는 것의 차이점은 무엇입니까?
Ming Li

3
이 두 개념이이 맥락에서 실제로 '직교'하지 않다는 것을 설명하는 것이 좋습니다. 두 개념이 서로 어떻게 비슷한 지 분명히 그릴 수 있습니다. 둘 이상의 것을 제어하는 ​​아이디어는 매우 유사합니다.
steviejay

8
Coroutines are a general control structure whereby flow control is cooperatively passed between two different routines without returning.<- 이것은 이다 동시성. 당신이 찾고있는 단어는 병렬 처리입니다.
Adam Arold

@steviejay orthogonal = Not similar to each other?
tonix

1
@tonix 나는 orthogonal"서로 독립적" 을 의미 한다고 들었습니다 .

77

에서 루아에서 프로그래밍 ", Coroutines"절 :

코 루틴은 스레드와 유사합니다 (멀티 스레딩의 의미). 자체 스택, 자체 로컬 변수 및 자체 명령 포인터가있는 실행 라인입니다. 그러나 전역 변수와 대부분 다른 코 루틴과 다른 것을 공유합니다. 스레드와 코 루틴의 주요 차이점은 개념적으로 (또는 문자 그대로 멀티 프로세서 시스템에서) 스레드가있는 프로그램이 여러 스레드를 병렬로 실행한다는 것입니다. 반면에 코 루틴은 협업 적입니다. 언제든지 코 루틴이있는 프로그램은 코 루틴 중 하나만 실행 중이며이 실행중인 코 루틴은 명시 적으로 일시 중지하도록 요청한 경우에만 실행을 일시 중단합니다.

요점은 코 루틴이 "협업"입니다. 다중 코어 시스템에서도 주어진 시간에 하나의 코 루틴 만 실행되지만 다중 스레드는 병렬로 실행될 수 있습니다. 코 루틴 사이에는 선점권이 없으며 실행중인 코 루틴은 실행을 명시 적으로 포기해야합니다.

" concurrency"의 경우 Rob Pike의 슬라이드를 참조 할 수 있습니다 .

동시성은 계산을 독립적으로 실행하는 구성입니다.

그래서 코 루틴 A의 실행 중에, 그것은 코 루틴 B로 제어 그리고 잠시 후, 코 루틴 B가 있으므로 코 루틴 A로 제어 다시 통과 통과 의존성 두 코 루틴은 그래서, 코 루틴 사이를, 그리고 그들이 협력하여 실행해야합니다 동시성 없습니다 .


6
코 루틴은 독립적으로 실행되지 않습니다. 그들은 교대로, 서로가 일의 일부를 할 때까지 기다립니다. 그들은 적극적으로 서로 협력합니다. 그것은 동시성에 대한 Rob Pikes 정의와 반대입니다.
Erick G. Hagstrom 2016 년

2
@ ErickG.Hagstrom : 독립적으로 실행되지는 않지만 모든 코 루틴의 논리는 독립적 일 수 있습니다. 그것이 맞다면, 그것은 하나의 코어 CPU에서 실행되는 비 선점 형 OS와 같습니다. 한 프로세스는 다른 작업을 실행하기 위해 CPU를 포기해야합니다.
Nan Xiao

6
다른 작업을 실행할 수 있도록 CPU를 포기하고 다른 특정 프로세스에 실행 시간을 알리는 것에는 차이가 있습니다. 코 루틴은 후자를한다. 그것은 어떤 의미에서도 독립적이지 않습니다.
Erick G. Hagstrom 2016 년

7
@ChrisClark 동의합니다. 코 루틴은 동시성입니다. wikipedia의 인용문은 다음과 같습니다. 코 루틴은 스레드와 매우 유사합니다. 그러나 코 루틴은 협력 적으로 멀티 태스킹되지만 스레드는 일반적으로 멀티 태스킹됩니다. 이것은 동시성을 제공하지만 병렬 처리는 제공하지 않음을 의미합니다 .
smwikipedia

3
그리고 : 또한 비 선점 형 멀티 태스킹으로 알려진 협동 멀티 태스킹, 운영 체제가 다른 프로세스로 실행중인 프로세스에서 컨텍스트 전환을 시작 적이있는 멀티 태스킹 컴퓨터의 스타일이다. 대신, 여러 응용 프로그램을 동시에 실행할 수 있도록 프로세스가 주기적으로 또는 유휴 상태이거나 논리적으로 차단 된 경우 자발적으로 제어를 수행합니다.
smwikipedia

47

기술적 인 질문이지만 대부분의 답변이 너무 기술적이라고 생각합니다. 나는 코 루틴 과정을 이해하려고 애썼다. 나는 그것을 얻는다. 그러나 나는 동시에 그것을 얻지 못한다.

나는이 답변이 매우 도움이된다는 것을 알았습니다.

https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9

Idan Arye에서 인용하려면 :

당신의 이야기를 바탕으로, 나는 이것을 다음과 같이 넣었습니다.

만화를보기 시작했지만 소개입니다. 인트로를 보지 않고 게임으로 전환하여 온라인 로비에 입장하십시오. 그러나 3 명의 플레이어가 필요합니다. 다른 플레이어가 참여하기를 기다리는 대신 숙제로 전환하고 첫 번째 질문에 대답하십시오. 두 번째 질문에는 시청해야하는 YouTube 동영상에 대한 링크가 있습니다. 열면로드가 시작됩니다. 로드되기를 기다리는 대신 만화로 다시 전환하십시오. 소개가 끝났으므로 볼 수 있습니다. 이제 광고가 있습니다-그러나 다른 플레이어가 합류하여 게임으로 전환하는 등.

아이디어는 한 번에 모든 작업을 수행하는 것처럼 보이도록 작업을 실제로 빠르게 전환하지는 않는다는 것입니다. 당신은 당신의 직접적인 관심이 필요한 다른 일들을하기 위해 당신이 일어나고있는 것을 기다리는 시간을 사용합니다.

링크를 확실히 확인하면 모든 것을 인용 할 수없는 것이 훨씬 많습니다.


6
매우 간단하고 간단한 그림. 이것을 위해 +1.
Taslim Oseni

좋은 그림. 나는 비슷한 이야기를 세웠다-포장을 모으기 위해 줄을 서서. 그러나 오늘, 당신은 훨씬 더 현실적입니다. 누가 door2door 배달이있을 때 줄을 서 있습니까? Lol
apolak

1
대단한 설명입니다. 인용 자체에서 그것은 분명합니다.
Farruh Habibullaev

15

코 루틴은 서브 루틴 / 스레드와 유사합니다. 차이점은 호출자가 서브 루틴 / 스레드를 호출하면 호출자 함수로 다시 돌아 가지 않습니다. 그러나 코 루틴은 몇 가지 코드를 실행 한 후 호출자가 자신의 코드 중 일부를 실행하고 실행이 중지 된 코 루틴 지점으로 돌아와서 계속 진행할 수 있도록 호출자에게 다시 돌아올 수 있습니다. 즉. 코 루틴에는 둘 이상의 진입 점과 출구 점이 있습니다


독립적이고 동시에 실행되는 스레드와는 다릅니다 (별도의 병렬 코어). 또한 서브 루틴 비교는 여러 개의 독립적 인 실행 경로가 있고 서로 결과를 리턴하지 않는다는 점에서 실패합니다.
javadba

11
  • 코 루틴은 코 틀린 언어에서 사용할 수있는 훌륭한 기능입니다
  • 코 루틴은 비동기 비 차단 코드를 작성하는 새로운 방법입니다.
  • 코 루틴은 가벼운 실입니다. 가벼운 스레드는 기본 스레드에 매핑되지 않으므로 프로세서의 컨텍스트 전환이 필요하지 않으므로 더 빠릅니다.
  • 네이티브 스레드에 매핑되지 않습니다
  • 코 루틴과 스레드는 모두 멀티 태스킹입니다. 그러나 차이점은 스레드가 OS에 의해 관리되고 사용자가 코 루틴을 관리한다는 것입니다.

기본적으로 두 가지 유형의 코 루틴이 있습니다.

  1. 스택리스
  2. 쌓다

Kotlin은 스택리스 코 루틴을 구현합니다. 즉, 코 루틴에는 자체 스택이 없으므로 기본 스레드에 매핑되지 않습니다.

코 루틴을 시작하는 기능은 다음과 같습니다.

launch{}

async{}

자세한 내용은 여기를 참조하십시오.

https://www.kotlindevelopment.com/deep-dive-coroutines/

https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9


1
좋은 대답입니다! Kotlin 및 Android 개발자에게 유용합니다.
Malwinder Singh

5

다른 말로, 파이썬 gevent라이브러리에는 coroutine스레드를 만들고 파괴하는 오버 헤드없이 비동기 네트워크 요청과 같은 스레드와 같은 기능을 제공 하는 기반 네트워킹 라이브러리가 있습니다. 사용 된 coroutine라이브러리는 greenlet입니다.


2

에서 파이썬 코 루틴 :

파이썬 코 루틴의 실행은 여러 시점에서 일시 중지되고 재개 될 수 있습니다 (코 루틴 참조). 코 루틴 함수 본문 내에서 대기 및 비동기 식별자는 예약 된 키워드가됩니다. await 식, async for 및 async with는 코 루틴 함수 본문에서만 사용할 수 있습니다.

루틴에서 (C ++ 20)

코 루틴은 나중에 다시 시작 하기 위해 실행을 일시 중지 할 수있는 기능입니다 . 코 루틴은 스택이 없으므로 호출자에게 반환하여 실행을 일시 중단합니다. 이를 통해 비동기식으로 실행되는 순차적 코드 (예 : 명시 적 콜백없이 비 차단 I / O 처리)를 수행 할 수 있으며 지연 계산 된 무한 시퀀스 및 기타 용도의 알고리즘도 지원합니다.

다른 사람의 대답과 비교하십시오.

내 의견으로는, 이력서의 뒷부분 은 @Twinkle과 마찬가지로 핵심 차이점입니다.
문서의 많은 필드가 여전히 진행 중이지만이 부분은 @Nan Xiao를 제외하고 대부분의 답변과 비슷합니다.

반면에 코 루틴은 협업 적입니다. 언제든지 코 루틴이있는 프로그램은 코 루틴 중 하나만 실행 중이며이 실행중인 코 루틴은 명시 적으로 일시 중지하도록 요청한 경우에만 실행을 일시 중단합니다.

Lua의 Program에서 인용되었으므로 언어와 관련이 있거나 (현재 Lua에 익숙하지 않음) 모든 문서가 유일한 부분을 언급 한 것은 아닙니다 .

동시과의 관계 :
의에 "실행"부분이 코 루틴 (C ++ 20) .Too 긴 여기에 인용합니다.
세부 사항 외에도 여러 상태가 있습니다.

When a coroutine begins execution  
When a coroutine reaches a suspension point  
When a coroutine reaches the co_return statement  
If the coroutine ends with an uncaught exception  
When the coroutine state is destroyed either because it terminated via co_return or uncaught exception, or because it was destroyed via its handle 

@ user217714의 답변 아래 @Adam Arold의 의견으로. 동시성입니다.
그러나 멀티 스레딩과는 다릅니다. std :: thread에서

스레드는 여러 함수가 동시에 실행될 수 있도록합니다. 스레드는 생성자 인수로 제공된 최상위 함수에서 시작하여 관련 스레드 개체가 생성되면 (OS 예약 지연에 따라) 즉시 실행을 시작합니다. 최상위 함수의 반환 값은 무시되며 예외를 throw하여 종료되면 std :: terminate가 호출됩니다. 최상위 함수는 std :: promise를 통해 또는 공유 변수를 수정하여 반환 값 또는 예외를 호출자에게 전달할 수 있습니다 (동기화가 필요할 수 있음 std :: mutex 및 std :: atomic 참조)

동시성이므로 특히 OS 대기 관점에서 대기가 불가피 할 때 멀티 스레딩과 같이 작동하므로 혼란 스럽습니다.


1

코 루틴은 특별한 종류의 서브 프로그램입니다. 기존의 서브 프로그램과 함께 존재하는 호출자와 호출 된 서브 프로그램 사이의 마스터-슬레이브 관계보다는 호출자와 호출 된 코 루틴이 더 평등합니다.

  • 코 루틴은 여러 개의 엔트리를 가지고 있고 스스로 제어하는 ​​서브 프로그램입니다 – Lua에서 직접 지원됩니다

  • 대칭 제어라고도합니다. 발신자와 코 루틴은보다 평등합니다.

  • 코 루틴 통화의 이름은 이력서입니다.

  • 코 루틴의 첫 번째 이력서는 시작이지만, 후속 호출은 코 루틴에서 마지막으로 실행 된 명령문 바로 다음에 시작됩니다.

  • 코 루틴은 서로 영원히, 아마도 영원히

  • 코 루틴은 프로그램 유닛 (코 루틴)의 유사 동시 실행을 제공합니다. 실행은 인터리브되지만 겹치지 않습니다.

예 1 예 2


1

링크 에서 설명 이 매우 간단 하다는 것을 알았습니다 . 이 답변 중 어느 것도이 답변의 마지막 글 머리 기호를 제외하고 동시성 대 병렬 처리를 설명하려고 시도 하지 않습니다 .

  1. 동시 (프로그램)이란 무엇입니까?

전설적인 Joe Armstrong의 "Erlang 프로그래밍"에서 인용 :

병렬 프로그램에서 동시 프로그램이 잠재적으로 더 빠르게 실행될 수 있습니다.

  • 동시 프로그램은 동시 프로그래밍 언어로 작성된 프로그램입니다. 우리는 성능, 확장 성 또는 내결함성의 이유로 동시 프로그램을 작성합니다.

  • 동시 프로그래밍 언어는 동시 프로그램 작성을위한 명시 적 언어 구성을 갖는 언어입니다. 이러한 구조는 프로그래밍 언어의 필수 요소이며 모든 운영 체제에서 동일한 방식으로 작동합니다.

  • 병렬 컴퓨터는 동시에 실행할 수있는 여러 처리 장치 (CPU 또는 코어)가있는 컴퓨터입니다.

따라서 동시성은 병렬 처리와 동일하지 않습니다. 단일 코어 컴퓨터에서 동시 프로그램을 계속 작성할 수 있습니다. 시간 공유 스케줄러를 사용하면 프로그램이 동시에 실행되고 있다고 느낄 수 있습니다.

동시 프로그램은 병렬 컴퓨터에서 병렬로 실행될 가능성이 있지만 보장되지는 않습니다 . OS는 프로그램을 실행하기위한 하나의 코어 만 제공 할 수 있습니다.

따라서 동시성은 동시 프로그램 의 소프트웨어 모델 로, 프로그램이 실제로 병렬로 실행될 수있는 것은 아닙니다.

  1. 코 루틴과 동시성

"코 루틴"이라는 단어는 "co"(협동) 및 "루틴"(기능)이라는 두 단어로 구성됩니다.

ㅏ. 동시성 또는 병렬 처리를 달성합니까?

간단하게 단일 코어 컴퓨터 에서 논의 해 봅시다 .

동시성은 OS의 시간 공유에 의해 달성됩니다. 스레드는 CPU 코어의 지정된 시간 프레임에서 코드를 실행합니다. OS에서 선점 할 수 있습니다. 또한 OS를 제어 할 수도 있습니다.

반면 코 루틴은 OS가 아닌 스레드 내의 다른 코 루틴에 대한 제어를 제공합니다. 따라서 스레드 내의 모든 코 루틴은 여전히 ​​OS에서 관리하는 다른 스레드에 CPU 코어를 제공하지 않고 해당 스레드의 시간 프레임을 이용합니다.

따라서 코 루틴이 OS (또는 준 병렬)가 아닌 사용자가 시간을 공유 한다고 생각할 수 있습니다 . 코 루틴은 해당 코 루틴을 실행하는 스레드에 할당 된 동일한 코어에서 실행됩니다.

코 루틴은 병렬 처리를 달성합니까? CPU 바인딩 코드 인 경우 아니요. 시간 공유와 마찬가지로 병렬로 실행되는 것처럼 느껴지지만 실행은 겹치지 않습니다. IO- 바운드라면 코드가 아닌 하드웨어 (IO 장치)에 의해 병렬 처리됩니다.

비. 함수 호출과의 차이점은 무엇입니까?

여기에 이미지 설명을 입력하십시오

그림에서 알 수 있듯이 return제어를 전환 하기 위해 호출 할 필요는 없습니다 . 없이 생산할 수 있습니다 return. 코 루틴은 현재 기능 프레임 (스택)에서 상태를 저장하고 공유합니다. 따라서 호출 스택을 스택하고 되감기 위해 레지스터와 로컬 변수를 저장할 필요가 없으므로 함수보다 훨씬 가볍습니다 call ret.


0

@ user21714의 답변을 확장하겠습니다. 코 루틴은 동시에 실행할 수없는 독립적 인 실행 경로입니다. python이러한 경로 간의 전환을 처리하기 위해 컨트롤러 ( 예 : 컨트롤러 라이브러리)에 의존 합니다. 그러나 이것이 작동하려면 코 루틴 자체가 yield실행을 일시 중지 할 수있는 유사한 구조 를 호출해야합니다 .

대신 스레드는 독립 컴퓨팅 리소스에서 서로 병렬로 실행됩니다. 서로 다른 리소스 를 사용하기 때문에 다른 실행 경로를 진행하기 위해 yield 를 호출 할 필요가 없습니다 .

예 - 당신은 multihreaded 프로그램을 시작하여이 효과를 볼 수있는 jvm응용 프로그램 - 당신의 모든 8 개에서 core i7하이퍼 스레드 코어가 사용됩니다 : 당신이 7백97% 활용도를 볼 수 있습니다 Activity Monitor또는 Top. 대신 일반적인 python프로그램을 실행하는 경우 ( coroutines또는 하나가있는 프로그램도) python threading사용률이 100 %로 최대가됩니다. 즉 하나의 시스템 하이퍼 스레드입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.