1 분 소요

1장 동시성 소개

무어의 법칙은 발열과 경제성 문제로 한계가 드러나며, 이를 극복하기 위해 멀티 코어 프로세서가 등장하였다. 소프트웨어의 속도 개선을 위해선 동시성 프로그래밍이 필요하다.

동시성이 어려운 이유

  • 레이스 컨디션
var data int
go func() {
    data++
}()

if data == 0 {
    fmt.Println("the value is %v\n", data)
}
# 결과
# 1. 아무것도 출력되지 않음
# 2. the value is 0
# 3. the value is 1

위에 결과가 나오는 것은 go문을 위에 썼다고 먼저 실행될거라 기대하는 프로그래머의 생각이다. 해당 문제를 해결하기 위해 time.Sleep()을 주는 것은 잘못된 행동이다.

  • 원자성

원자성은 특정 실행 컨텍스트에서 더 이상 나눌 수 없는 연산을 얘기함.

따라서 같은 메모리를 사용하면 원자적이지 않다고 할 수 있다.

i 값을 다른 고루틴들에게 노출하지 않는 고루틴의 컨텍스트인 경우 원자적이다.

동시에 수행되는 프로세스들이 없는 프로그램의 컨텍스트라면 원자적이다.

  • 메모리 접근 동기화
package main

import "fmt"

func main() {
    var value int
    go func() {
        value++
    }()
    if value == 0 {
        fmt.Println("the value is 0")
    } else {
        fmt.Println("the value is ", value)
    }
}

결과를 예측 할 수 없음

package main

import (
	"fmt"
    "sync"
)

func main() {
    var (
        memoryAccess sync.Mutext
        value int
    )
    go func() {
        memoryAccess.Lock()
        value++
        memoryAccess.UnLock()
    }()
    memoryAccess.Lock()
    if value == 0 {
        fmt.Println("the value is 0")
    } else {
        fmt.Println("the value is ", value)
    }
    memoryAccess.UnLock()
}

Lock으로 자원의 접근을 막았지만 레이스 컨디션을 막을 수 없어 결과는 동일함

sync.atomic이라는 원자성 카운터 기능 제공

  • 데드락

    모든 쓰레드가 잠들어있거나 대기하는 상황

  • 라이브락

    프로그램들이 활동적으로 동시에 연산을 수행하고는 있지만 이연산들이 실제로 프로그램의 상태를 진행시키는데 아무런 영향을 줄 수 없을 때

  • 기아상태

​ 한프로세스가 다른 프로세스의 비해 많은 자원을 점유할 때

  • 동시실행 안정성 판단
    • 누가 동시성을 책임지는가?
    • 누가 동기화를 책임지는가?
    • 문제 공간은 동시성 기본요인에 어떻게 매핑되는가?

댓글남기기