1.쓰레드 - 프로세스 안의 세부 작업 단위, 실행 흐름
(1)컨텍스트 스위치 비용 - CPU 코어가 여러 쓰레드를 전환하면서 수행하면서 생기는 비용
(2)쓰레드 컨텍스트 - 쓰레드가 다시 전환되어 돌아올 때, 마지막 실행한 상태부터 이어서 실행할 수 있게 보관 -> 이때, 쓰레드의 명령 포인터, 스택 메모리 등의 정보를 저장한 것
-> 너무 많은 쓰레드 수행 시 성능 저하(보통 코어 개수의 두 배 이상 시 스위치 비용 커짐)
2.고루틴 - OS 쓰레드(운영체제가 제공하는 쓰레드)를 이용하는 경량 쓰레드
CPU코어마다 OS쓰레드를 하나만 할당해서 사용하기 때문에 컨텍스트 스위칭 비용 발생 X
(1)서브 고루틴 종료 시까지 대기
var wg sync.WaitGroup
wg.Add(3)//작업 개수 설정(기다릴 총 작업 개수 설정)
wg.Done()//작업이 완료될 때마다 호출(위에서 설정한 3번이 호출되어야 됨)
wg.Wait()//모든 작업이 완료될 때까지 대기(Done()이 위에서 설정한 3번 호출 될 때까지 대기)
(2)동작 방법 - CPU코어가 2개이고 실행하려는 고루틴이 3개일 때
-> 1, 2, 3 순차적으로 들어올 때
-> 1, 2는 각각 OS 쓰레드에서 실행되고 3은 남는 코어가 생길 때까지 실행되지 않고 대기
(3)시스템 콜 - 운영 체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스 ex)프로세스 제어, 파일 조작, 장치 조작, 정보 유지보수, 통신과 보호
만약 1, 2 실행 중 2번 고루틴이 네트워크 수신 대기 시 고루틴3이 OS쓰레드를 이용하여 실행, 고루틴2는 대기
3.동시성 프로그래밍 주의점 - 같은 자원에 여러 고루틴 접근(ex) 같은 map에 접근하여 값 변경)
4.뮤텍스를 이용하여 동시성 문제 해결
(1)뮤텍스(Mutex) - 자원 접근 권한 지정
package main
import (
"sync"
"strconv"
)
var mutex sync.Mutex
type Student struct {
Subject map[string]string
}
func (s *Student)ChangeSubject(key string, value string) {
mutex.Lock()//뮤텍스 확보될 때까지 대기(Unlock()될 때까지 대기)
defer mutex.Unlock()//뮤텍스 반납
s.Subject[key] = value
}
func main() {
var wg sync.WaitGroup
s := &Student{}
s.Subject = make(map[string]string)
s.Subject["Math"] = "2"
wg.Add(2)
for i := 0; i < 2; i++ {
go func() {
defer wg.Done()
s.ChangeSubject("Math", strconv.Itoa(i))
}
}
wg.Wait()
}
(2)데드락 - 어떤 고루틴도 원하는 만큼 뮤텍스를 확보하지 못하고 무한히 대기하는 상태
5.다른 방법
(1)각기 다른 구조체 생성하여 작업
(2)각기 다른 작업을 실행
'Golang' 카테고리의 다른 글
[Golang] Closure (0) | 2022.04.18 |
---|---|
[Golang] 채널, 컨텍스트 (0) | 2022.04.18 |
[Golang] Gin-Swagger (0) | 2022.03.30 |
[Golang] 에러 핸들링 (0) | 2022.03.24 |
[Golang] 자료구조 (0) | 2022.03.23 |