go-langs goroutine pool은 단지 녹색 스레드입니까?


47

해설자는 여기에 녹색 스레드의 다음과 같은 비판을 제공합니다 :

콜백 지옥없이 이벤트 중심 프로그래밍을하는 수단으로 N : M 모델에서 처음 판매되었습니다. 오래된 절차 적 코드처럼 보이는 코드를 작성할 수 있지만 그 아래에는 무언가 차단 될 때마다 사용자 공간 작업 전환을 사용하는 마술이 있습니다. 잘 들린다. 문제는 더 복잡한 복잡성을 해결한다는 것입니다. swapcontext () 및 family는 상당히 해방되어 복잡성은 의도하지 않은 다른 장소에서 비롯됩니다.

갑자기 사용자 공간 스케줄러를 작성하고 수년간의 노력을 기울인 Linux의 스케줄보다 더 나은 작업을 수행하는 스케줄러를 작성하는 것이 실제로 어려운 일을 추측해야합니다. 이제 N 개의 녹색 스레드를 M 개의 물리적 스레드로 관리하도록 스케줄을 설정해야하므로 동기화에 대해 걱정해야합니다. 동기화는 성능 문제를 가져 오므로 이제 새로운 잠금없는 토끼 구멍을 뚫으십시오. 정확한 동시 스케줄러를 작성하는 것은 쉬운 일이 아닙니다.

또 다른 비판은 다음과 같습니다.

여러 스레드를 속이는 단일 프로세스에는 많은 문제가 있습니다. 그중 하나는 모든 가짜 스레드가 모든 페이지 결함에서 중단된다는 것입니다.

내 질문입니다 - 이다 이동 - 랭의 goroutines을 (기본 풀) 단지 녹색 스레드는? 그렇다면 위의 비판을 다루고 있습니까?

답변:


67

나는 캐주얼 한 Go 사용자이므로 소금 한 알로 다음을 복용하십시오.

위키 백과는 녹색 스레드 를 "기본 운영 체제가 아닌 가상 머신 (VM)이 예약 한 스레드"로 정의합니다 . 녹색 스레드는 기본 OS 기능에 의존하지 않고 멀티 스레드 환경을 에뮬레이션하며 커널 공간 대신 ​​사용자 공간에서 관리되므로 기본 스레드 지원이없는 환경에서 작동 할 수 있습니다.

Go (또는보다 정확하게 기존의 두 구현)는 기본 코드 만 생성하는 언어이며 VM을 사용하지 않습니다. 또한 현재 런타임 구현의 스케줄러는 OS 레벨 스레드 (GOMAXPROCS = 1 인 경우에도)에 의존합니다. Go 모델의 녹색 스레드에 대한 이야기는 약간 모욕적이라고 생각합니다.

Go 사람들은 다른 동시성 메커니즘 (예 : 코 루틴 또는 스레드 또는 경량 프로세스)과의 혼동을 피하기 위해 고 루틴 용어를 만들었습니다.

물론 Go는 M : N 스레딩 모델을 지원하지만 Java 녹색 스레드 모델보다 Erlang 프로세스 모델에 훨씬 더 가깝습니다.

다음은 초기 JVM에서 구현 된 녹색 스레드보다 Go 모델의 몇 가지 이점입니다.

  • 개발자에게 투명한 방법으로 여러 개의 코어 또는 CPU를 효과적으로 사용할 수 있습니다. Go를 사용하면 개발자는 동시성을 관리해야합니다. Go 런타임은 병렬 처리를 처리합니다. Java 그린 스레드 구현은 여러 코어 또는 CPU로 확장되지 않았습니다.

  • 시스템 및 C 호출은 스케줄러에 대한 비 차단입니다 (이벤트 루프에서 다중화 된 I / O를 지원하는 것뿐만 아니라 모든 시스템 호출). 녹색 스레드 구현은 차단 시스템 호출이 완료 될 때 전체 프로세스를 차단할 수 있습니다.

  • 복사 또는 세그먼트 화 된 스택. Go에서는 고 루틴에 최대 스택 크기를 제공 할 필요가 없습니다. 필요에 따라 스택이 점차 커집니다. 한 가지 결과는 고 루틴이 많은 메모리 (4KB-8KB)를 필요로하지 않기 때문에 많은 수의 메모리가 행복하게 생성 될 수 있다는 것입니다. 따라서 고 루틴 사용량은 광범위 할 수 있습니다.

이제 비판을 다루기 위해 :

  • Go를 사용하면 사용자 공간 스케줄러를 작성할 필요가 없습니다. 이미 런타임과 함께 제공됩니다. 복잡한 소프트웨어이지만 Go 사용자가 아닌 Go 개발자의 문제입니다. Go 사용자에게는 사용법이 투명합니다. Go 개발자 중 Dmitri Vyukov 는 잠금 해제 / 대기없는 프로그래밍 전문가이며 특히 스케줄러의 최종 성능 문제를 해결하는 데 관심이있는 것 같습니다. 현재 스케줄러 구현이 완벽하지는 않지만 향상됩니다.

  • 동기화는 성능 문제와 복잡성을 가져옵니다. 이것은 Go에서도 부분적으로 사실입니다. 그러나 Go 모델은 동시 고 루틴에서 채널 사용과 프로그램의 완전한 분해를 촉진하여 동기화 복잡성을 제한합니다 (즉, 통신을 위해 메모리를 공유하는 대신 데이터를 공유하여 통신). 그건 그렇고, 참조 Go 구현은 프로파일 러경주 탐지기 와 같은 성능 및 동시성 문제를 해결하기위한 많은 도구를 제공합니다 .

  • 페이지 오류 및 "다중 스레드 페이 킹"과 관련하여 Go는 여러 시스템 스레드에서 고 루틴을 예약 할 수 있습니다. 어떤 이유로 든 하나의 스레드가 차단되면 (페이지 오류, 시스템 호출 차단) 다른 스레드가 다른 고 루틴을 계속 예약하고 실행하는 것을 막지 않습니다. 이제 페이지 오류로 인해 OS 스레드가 차단되고 모든 고 루틴이이 스레드에서 예약되어야합니다. 그러나 실제로 Go 힙 메모리는 스왑 아웃되지 않아야합니다. Java에서도 마찬가지입니다. 가비지 수집 언어는 가상 메모리를 매우 잘 수용하지 못합니다. 프로그램이 페이지 결함을 정상적으로 처리해야하는 경우 일부 오프 메모리를 관리해야하기 때문일 수 있습니다. 이 경우

따라서 IMO에서 고 루틴은 녹색 스레드가 아니며 Go 언어 및 현재 구현은 대부분 이러한 비판을 해결합니다.


1
질문에 대한 훌륭하고 자세한 답변 :)
Tuxdude

1
나는이 답변을 좋아하지만 OS 스레드가 어떻게 / 언제 만들어 지는지에 대한 언급이 있습니까?
Lars

1
Go Language의 가장 큰 단점 중 하나는 모든 차단 시스템 호출에 대해 커널 스레드를 생성한다는 것입니다!
user1870400

8
Wikipedia의“그린 스레드”기사가“ 런타임 라이브러리 또는 VM (가상 머신)에 의해 예약 된 스레드”상태로 변경되었습니다 . 즉, Go 런타임이 예약 / 관리를 수행하므로 해당 정의에 따라 더 이상 답변이 정확하지 않습니다. OS 스레드와 대조되는 사용자 공간 스레드로 녹색 스레드를 정의하는 것이 더 도움이된다고 생각합니다. 그리고, goroutines는 확실히 녹색 실입니다.
mknecht

1
두 번째 @mknecht. VM에 관한 것이 아니라 런타임에 관한 것입니다. 그리고 Go에는 확실히 런타임이 있습니다. (스레딩 모델 및 가비지 수집을 관리합니다).
팀 하퍼
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.