robert-min / project-go

Go 언어 리뷰와 기존에 파이썬으로 진행했던 프로젝트를 Go 언어로 개선한 repo
0 stars 0 forks source link

Go routine #12

Open robert-min opened 11 months ago

robert-min commented 11 months ago

Go routine

sync.WaitGroup

package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func PrintHangle() {
    hanguls := []rune{'가', '나', '다', '라'}
    for _, v := range hanguls {
        time.Sleep(300 * time.Millisecond)
        fmt.Printf("%c ", v)
    }
    wg.Done()
}

func PrintNumbers() {
    for i := 1; i <= 5; i++ {
        time.Sleep(400 * time.Millisecond)
        fmt.Printf("%d ", i)
    }
    wg.Done()
}

func main() {
    wg.Add(2)
    go PrintHangle()
    go PrintNumbers()

    wg.Wait()
}
robert-min commented 11 months ago

고루팀 사용시 동일한 메모리 자원 접근 시 문제

package main

import (
    "fmt"
    "sync"
    "time"
)

var mutex sync.Mutex

type Account struct {
    Balance int
}

func DepositAndWithdraw(account *Account) {
    // mutex 획득
    mutex.Lock()
    defer mutex.Unlock()

    if account.Balance < 0 {
        panic(fmt.Sprintf("Balance sould not be negative value : %d", account.Balance))
    }
    account.Balance += 1000
    time.Sleep(time.Millisecond)
    account.Balance -= 1000
}

func main() {
    var wg sync.WaitGroup

    account := &Account{0}
    wg.Add(10)

    for i := 0; i < 10; i++ {
        go func() {
            for {
                DepositAndWithdraw(account)
            }
            wg.Done()
        }()
    }
    wg.Wait()

}
robert-min commented 11 months ago

Channel

package main

import (
    "fmt"
    "sync"
    "time"
)

func square(wg *sync.WaitGroup, ch chan int) {
    for n := range ch {
        fmt.Printf("Square: %d\n", n*n)
        time.Sleep(time.Second)
    }
    wg.Done()
}

func main() {

    var wg sync.WaitGroup
    ch := make(chan int)

    wg.Add(1)
    go square(&wg, ch)

    for i := 0; i < 10; i++ {
        ch <- i * 2
    }
    // 데이터를 모두 넣고 필요 없어진 채널을 닫음
    close(ch)
    wg.Wait()

}
robert-min commented 11 months ago

Chan Select

package main

import (
    "fmt"
    "sync"
    "time"
)

func square(wg *sync.WaitGroup, ch chan int, quit chan bool) {
    for {
        select {
        case n := <-ch:
            fmt.Printf("Square: %d\n", n*n)
            time.Sleep(time.Second)
        case <-quit:
            wg.Done()
            return
        }
    }
}

func main() {
    var wg sync.WaitGroup
    ch := make(chan int)
    quit := make(chan bool)

    wg.Add(1)
    go square(&wg, ch, quit)

    for i := 0; i < 10; i++ {
        ch <- i * 2
    }

    quit <- true
    wg.Wait()
}
robert-min commented 11 months ago

Context

작업 취소가 가능한 컨텍스트

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func PrintEverySecond(ctx context.Context) {
    tick := time.Tick(time.Second)
    for {
        select {
        case <-ctx.Done():
            wg.Done()
            return
        case <-tick:
            fmt.Println("Tick")
        }
    }
}

func main() {
    wg.Add(1)
    // context 생성
    ctx, cancel := context.WithCancel(context.Background())
    go PrintEverySecond(ctx)
    time.Sleep(5 * time.Second)
    cancel()

    wg.Wait()

}

특정 값을 설정한 컨택스트

package main

import (
    "context"
    "fmt"
    "sync"
)

var wg sync.WaitGroup

func squre(ctx context.Context) {
    if v := ctx.Value("number"); v != nil {
        n := v.(int)
        fmt.Printf("Squre: %d", n*n)
    }
    wg.Done()
}

func main() {
    wg.Add(1)
    // context 생성
    ctx := context.WithValue(context.Background(), "number", 9)
    go squre(ctx)

    wg.Wait()

}