go sync. map 구현

golang map 는 goroutine 이 아 닌 안전 합 니 다. 여러 goroutine 이 map 를 사용 하려 면 잠 금 이 필요 합 니 다.그러나 높 은 병발 장면 에서 자물쇠 의 경쟁 용 은 시스템 성능 을 떨 어 뜨 릴 수 있다.이러한 문 제 를 해결 하기 위해 go 1.9 이후 스 레 드 안전 을 제공 합 니 다: sync. map.sync. map 는 두 개의 데이터 구조 read, dirty 를 도입 하여 저장 합 니 다. 그들의 바 텀 은 모두 map 로 이 루어 집 니 다.
Golang 은 CAS 와 같은 잠 금 을 넣 지 않 는 방안 을 선택 하여 값 을 업데이트 하고 동시에 안전 한 맵 을 실현 합 니 다.
다음은 세 개의 구조 체 를 예 로 들 었 다.
map: sync. map 의 구조 체 는 read 와 dirty, read 와 dirty 를 포함 하여 map 에 실제 저 장 된 key / value 값 을 저장 합 니 다.misses 는 dirty 에서 값 을 읽 는 횟수 readonly: Map. read 값 의 구조 체 유형, m 저장 key / value 의 실제 값 을 표시 합 니 다.readOnly. amended 는 read 가 dirty 던 전 entry: read 와 dirty 에 value 를 저장 하 는 지침 을 만 들 었 는 지 여 부 를 표시 합 니 다.
type Map struct {
    mu Mutex
    read atomic.Value // readOnly
    dirty map[interface{}]*entry
    misses int
}

type readOnly struct {
    m       map[interface{}]*entry
    amended bool 
}

type entry struct {
    p unsafe.Pointer // *interface{}
}

read 는 readOnly 구조 체 로 실제 데 이 터 는 readOnly. m 에 저 장 됩 니 다.
read 와 dirty 의 연결:
1: read 는 cache 에 해당 합 니 다. 데 이 터 를 읽 을 때 read 에서 읽 고 찾 지 못 했 습 니 다. dirty 에서 읽 습 니 다. Map. misses +.Map. misses 가 dirty 길이 에 이 르 렀 을 때 dirty 안의 데 이 터 를 모두 read 에 복사 하고 dirty 를 nil 로 설정 합 니 다.
2: read 와 dirty map 에 저 장 된 요소 값 은 entry 구조 체 에 있 습 니 다.read 와 dirty 의 같은 key 값 은 같은 entry 주 소 를 가리 키 기 때문에 read 의 key 에 대응 하 는 value 값 을 수정 하면 dirty 의 값 도 상응 하 게 수 정 됩 니 다.
entry. p 의 상태: 1: nil 은 entry 가 삭제 되 었 음 을 표시 하고, Map. dirty = nil 2: expunged (초기 화 된 entry. p) 는 entry 가 삭제 되 었 음 을 표시 하지만, Map. dirty! =nil 3: 기타 상황 표시 값 존재
snyc. Map 은 주로 삽입, 찾기, 삭제 작업 을 제공 합 니 다. 다음은 이 세 가지 방법의 실현 을 이야기 할 것 입 니 다.
프로 세 스 삽입 key, value 1: read 에서 key 를 가 져 옵 니 다. 존재 하고 이 key 가 삭제 되 지 않 으 면 read [key] = entry {p: value} 를 직접 업데이트 하여 2 로 되 돌려 줍 니 다. 그렇지 않 으 면 key 가 존재 하지만 삭제 되 었 습 니 다. dirty 에 이 key, value 값 을 삽입 합 니 다.dirty [key] = entry {p: value} 을 3 으로 되 돌려 줍 니 다. dirty 가 nil 이면 read map 의 key, entry 를 새로 만 든 dirty map 에 추가 합 니 다.nil 이 아 닌 3 단 계 를 건 너 뛰 기 4: key, value 를 dirty map 에 삽입 합 니 다.dirty[key] = entry{p: value}
요약 삽입: 새로 추 가 된 key 값 은 dirty 에 이전에 존재 하지만 삭 제 된 key 를 삽입 합 니 다. dirty 에 이전에 존재 하지만 삭제 되 지 않 은 key 를 삽입 합 니 다. read 는 이 key 에 대응 하 는 value 값 을 업데이트 하기 때문에 dirty 가 nil 이 아 닐 때 key 값 을 전량 저장 합 니 다.
검색 프로 세 스 검색 key 1: read 에서 읽 고 2 로 되 돌아 갑 니 다. 읽 지 못 했 고 dirty 는 nil 이 아 닙 니 다. map 에 자 물 쇠 를 추가 한 다음 read map 의 내용 을 다시 읽 습 니 다.그리고 map. misses +.map. misses 가 일정한 dirty 길이 에 이 르 렀 을 때 dirty map 를 모두 read map 에 복사 하고 dirty 를 nil 로 설정 합 니 다.
찾기 요약: read 를 읽 지 못 했 습 니 다. dirty 에서 읽 습 니 다. 그리고 misses 횟수 + 1. 횟수 가 일정한 dirty 길이 에 이 르 면 dirty map 를 모두 read map 로 복사 하고 dirty 를 nil 로 설정 합 니 다.
삭제 프로 세 스 1: read 에서 key 를 읽 습 니 다. 존재 하면 read [key] 에서 entry. p 를 nil 2 로 가 져 옵 니 다. 그렇지 않 으 면 dirty 에서 이 key 값 을 삭제 하기 때문에 read 삭 제 는 entry 의 p 를 nil 로 직접 설정 하고 key 를 보존 합 니 다.dirty 에서 삭제 하 는 것 은 바로 이 key 를 삭제 하 는 것 입 니 다.

좋은 웹페이지 즐겨찾기