golang 의 select 실현 원리 분석
select 는 golang 에 다 중 IO 재 활용 체 제 를 제공 합 니 다. 다른 IO 재 활용 과 마찬가지 로 읽 기와 쓰기 이벤트 가 ready 되 었 는 지 확인 하 는 데 사 용 됩 니 다.
본 고 는 골 랑 의 select 의 용법 과 실현 원 리 를 소개 할 것 이다.
실현 원리
golang 이 select 를 실현 할 때 실제 적 으로 모든 case 문 구 를 하나의 데이터 구 조 를 정의 합 니 다. selection 문 구 를 실행 할 때 실제 적 으로 하나의 case 배열 로 처 리 된 코드 블록 (또는 함수) 을 비교 한 다음 에 프로그램 절 차 는 선택 한 case 블록 으로 이동 할 수 있 습 니 다.
케이스 데이터 구조
소스 패키지
src/runtime/select.go:scase
는 case 문 구 를 나타 내 는 데이터 구 조 를 정의 했다.type scase struct {
c *hchan // chan
kind uint16
elem unsafe.Pointer // data element
}
scase. c 는 현재 case 문 구 를 조작 하 는 chan 지침 을 표시 합 니 다. 이것 은 하나의 case 가 하나의 chan 만 감청 할 수 있 음 을 나타 냅 니 다.
scase. kind 는 현재 chan 이 읽 을 수 있 는 지, 쓸 수 있 는 channel 또는 default 인지 표시 합 니 다.세 가지 유형 은 각각 상수 로 정의 된다.
select 실현 논리
원본 패키지
src/runtime/select.go:selectgo()
는 select 선택 case 의 함 수 를 정의 합 니 다.// selectgo implements the select statement.
//
// *sel is on the current goroutine's stack (regardless of any
// escaping in selectgo).
//
// selectgo returns the index of the chosen scase, which matches the
// ordinal position of its respective select{recv,send,default} call.
func selectgo(sel *hselect) int {
}
그 중에서 데이터 구조 hselect 는 다음 과 같다.
// Select statement header.
// Known to compiler.
// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
type hselect struct {
tcase uint16 // total count of scase[]
ncase uint16 // currently filled scase[]
pollorder *uint16 // case poll order
lockorder *uint16 // channel lock order
scase [1]scase // one per case (in order of appearance)
}
hselect. tcase 에 저 장 된 것 은 scase 총수 입 니 다.
hselect. pollorder 는 scase 의 무 작위 적 인 배열 을 저장 합 니 다.무 작위 검사 케이스 의 목적 을 달성 하 다.
hselect. lockorder 는 저 장 된 channel 주소 입 니 다.모든 case 구문 에서 channel 서열 은 channel 에 자 물 쇠 를 추가 할 때 반복 적 으로 자 물 쇠 를 추가 하 는 것 을 방지 하 는 목적 을 달성 합 니 다.
selectgo 는 int 로 돌아 가 선택 한 scase, 즉 ready 의 channel index 를 표시 합 니 다.
이 함수 의 실행 논 리 는 대체로 다음 과 같다.
1. scase 문장의 모든 channel 잠 금
2. 무 작위 순서 로 scase 의 channel ready 여 부 를 검사 합 니 다.
2.1 case 가 읽 을 수 있다 면 channel 의 데 이 터 를 읽 고 모든 channel 을 잠 그 고 되 돌려 줍 니 다 (case index)
2.2 case 가 쓸 수 있다 면 데 이 터 를 channel 에 기록 하고 모든 channel 의 잠 금 을 풀 고 되 돌려 줍 니 다 (case index)
2.3 모든 case 가 ready 되 지 않 으 면 모든 channel 을 잠 그 고 되 돌려 줍 니 다 (default index)
3. 모든 케이스 가 준비 되 지 않 았 고 default 문구 가 없습니다.
3.1 현재 협 정 을 모든 channel 대기 열 에 추가 합 니 다.
3.2 협 정 을 차단 으로 전환 하고 깨 어 날 때 까지 기다린다.
4. 각성 후 채널 에 대응 하 는 case index 로 되 돌아 가기
4.1 읽 기 동작 이 라면 모든 channel 을 잠 그 고 되 돌려 줍 니 다 (case index)
4.2 쓰기 동작 이 라면 모든 channel 을 잠 그 고 되 돌려 줍 니 다 (case index)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.