본문 바로가기
프로그래밍/golang

ultimate in go-(9) 동시성(고루틴)

by 나도한강뷰 2023. 1. 26.

고루틴(goroutine)

go 스케쥴러

  • go가 시작할때, 사용 가능 코어 개수를 확인한다.
  • os 스레드 m개와 소프트웨어 스레드 n개를 잘 스케줄링하는것이 go runtime의 역할중 하나이다.
  • 이러한 작동은 하이퍼스레딩, 코어당 스레드 수, 클럭 주기등의 요소를 반영하여서 작동한다.
  • 작동방식 예시
    • 프로세서 p는 os 스레드 m을 할당받아서 작동한다.
    • 리눅스의 스케줄러에는 실행 대기열이 존재한다.(go에는 global run queue(GRQ)가 존재하며, p에는 local run queui(LRQ)가 존재한다.)
    • go프로그램 시작시, 런타임은 고루틴을 생성한다.
    • 특성 프로세서 p를 LRQ에 넣는다
    • 고루틴은 스레드와 같이 sleeping, executing, runnable(하드웨어에 의해서 실행될때까지 대기)상태에 놓인다.
    • 스레드를 스케쥴링하고 코어에서 실행하는건 os가 한다.
    • 그 스레드위에서 다중화되어서 스케쥴링하는건 런타임이 한다.
    • GRQ에 있는 애들을 꺼내서 LRQ에 할당후 실행요청한다.
    • 이 대기열은 FIFO를 따르지 않는다.
    • ultimate in go 한글번역이 약간 똥인거같다...
package main
import (
    "fmt"
    "runtime"
    "sync"
)
func init() {
    runtime.GOMAXPROCS(1)
}
func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    fmt.Println("Start Goroutines")
    go func() {
        lowercase()
        wg.Done()
    }()
    go func() {
    uppercase()
    wg.Done()
    }()
    fmt.Println("Waiting To Finish")
    wg.Wait()
    fmt.Println("\nTerminating Program")
}
func lowercase() {
    for count := 0; count < 3; count++ {
        for r := 'a'; r <= 'z'; r++ {
            fmt.Printf("%c ", r)
        }
    }
}
func uppercase() {
    for count := 0; count < 3; count++ {
        for r := 'A'; r <= 'Z'; r++ {
            fmt.Printf("%c ", r)
        }
    }
}
Start Goroutines
Waiting To Finish
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d
e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n
o p q r s t u v w x y z
Terminating Program
  • goprocess의 최대수를 1로 설정한다.
  • wg를 통해서 동시에 실행되는 2개의 goroutine을 동시에 끝낼수 있게 조정한다.
  • process가 하나이기때문에 goroutine2개중 1개씩 코어에 할당되고, 실행되게 된다.
  • 그렇기때문에 순차적으로 lowercase uppercase가 실행되는 것으로 보인다.
  • 이프로그램의 runtime.GOMAXPROCS(2)로 변경하게되면
    Start Goroutines
    Waiting To Finish
    a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j
    k l m n o p A B C D E F G H I J K L M N O P Q R S q r s t u v w x y z a
    b c d e f g h i j k l m n o p q r s t u v w x y z T U V W X Y Z A B C D
    E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
    O P Q R S T U V W X Y Z
    Terminating Program
  • 위와같이 동시에 병렬적으로 실행되는 것을 알수 있다.
  • 첫번째 케이스는 동시적으로 프로그래밍되었지만, 병렬적으로 처리가 안된케이스고
  • 두번째 케이스는 동시적으로 프로그래밍되었고, 병렬적으로 처리가 된 케이스이다.

'프로그래밍 > golang' 카테고리의 다른 글

ultimate in go-(11) 채널  (1) 2023.01.29
ultimate in go-(10) data race  (0) 2023.01.29
ultimate in go (8)- interface변환 및 주의사항  (0) 2023.01.25
ultimate in go(7)- decoupling  (0) 2023.01.24
ultimate in go (6)- grouping  (0) 2023.01.24