Golang

[Golang] 고루틴과 동시성

GenieLove! 2022. 4. 17. 01:18
728x90
반응형

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)각기 다른 작업을 실행

728x90
반응형

'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