goroutine

๊ธฐ๋ณธ์ •๋ณด

  • ์“ฐ๋ ˆ๋“œ

  • ํ”„๋กœ์„ธ์Šค

๊ณ ๋ฃจํ‹ด

๊ณ ๋ฃจํ‹ด์€ ๊ฒฝ๋Ÿ‰ ์“ฐ๋ ˆ๋“œ๋กœ ํ•จ์ˆ˜๋‚˜ ๋ช…๋ น์„ ๋™์‹œ์— ์‹คํ–‰ํ• ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ณ ๋ฃจํ‹ด์€ os ์“ฐ๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒฝ๋Ÿ‰ ์“ฐ๋ ˆ๋“œ ์ด๋‹ค.

์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ : ์“ฐ๋ ˆ๋“œ ์ „ํ™˜์—๋Š” ๋น„์šฉ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด๊ฒƒ์„ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋ณดํ†ต ์ฝ”์–ด ๊ฐฏ์ˆ˜์˜ ๋‘๋ฐฐ์ด์ƒ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด ์Šค์œ„์นญ ๋น„์šฉ์ด ๋งŽ์ด ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์“ฐ๋ ˆ๋“œ ๊ฐฏ์ˆ˜์™€ ์ฝ”์–ด ๊ฐฏ์ˆ˜๊ฐ€ ๊ฐ™๋‹ค๋ช… ์–ด๋–ป๊ฒŒ ๋ ๊ฐ€?

CPU ์ฝ”์–ด๋งˆ๋‹ค OS ์“ฐ๋ ˆ๋“œ๋ฅผ ํ•˜๋‚˜๋งŒ ํ• ๋‹นํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ์ข‹๋‹ค.

๋ฉ”์ธ ํ•จ์ˆ˜๋„ ๊ณ ๋ฃจํ‹ด - ๋ฉ”์ธ ๊ณ ๋ฃจํ‹ด์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์ƒˆ๋กœ์šด ๊ณ ๋ฃจํ‹ด์€ ๋‹จ์ˆœํžˆ go ํ•จ์ˆ˜ ๋กœ ๋งŒ๋“ ๋‹ค.

package main

import (
  "fmt"
  "time"
)

func PrintHangul() {
  hanguls := []rune{'๊ฐ€', '๋‚˜', '๋‹ค', '๋ผ', '๋งˆ', '๋ฐ”', '์‚ฌ'}
  for _, v := range hanguls {
    time.Sleep(300 * time.Millisecond)
    fmt.Printf("%c ", v)
  }
}

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

func main() {
  go PrintHangul()
  go PrintNumbers()

  time.Sleep(3 * time.Second)
}

๋ฉ”์ธ ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์•„๋ฌด๋ฆฌ ๋งŽ์€ ๊ณ ๋ฃจํ‹ด์ด ์ƒ์„ฑ๋˜์–ด ์ž‡๋”๋ผ๋„ ๋ชจ๋‘ ์ฆ‰์‹œ ์ข…๋ฃŒ๋˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ธŒ ๊ณ ๋ฃจํŒ…์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ

sync ํŒจํ‚ค์ง€์˜ WaitGroup๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค.

var wg sync.WaitGroup

wg.Add(3)
wg.Done()
wg.Wait()
package main

import (
  "fmt"
  "sync"
)

var wg sync.WaitGroup // โถ waitGroup ๊ฐ์ฒด

func SumAtoB(a, b int) {
  sum := 0
  for i := a; i <= b; i++ {
    sum += i
  }
  fmt.Printf("%d๋ถ€ํ„ฐ %d๊นŒ์ง€ ํ•ฉ๊ณ„๋Š” %d์ž…๋‹ˆ๋‹ค.\n", a, b, sum)
  wg.Done()
}

func main() {
  wg.Add(10) // โท ์ด ์ž‘์—… ๊ฐœ์ˆ˜ ์„ค์ •
  for i := 0; i < 10; i++ {
    go SumAtoB(1, 1000000000)
  }

  wg.Wait() // โน ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆผ.
  fmt.Println("๋ชจ๋“  ๊ณ„์‚ฐ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
}

์“ฐ๋ ˆ๋“œ ํ’€์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š”๋“ฏ. ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ฝ”์–ด๋ฅผ ๊ฐ™์ด ์“ธ์ˆ˜๊ฐ€ ์ž‡๊ฒŒ ๋˜๊ฒŸ์Œ os ์“ฐ๋ ˆ๋“œ๋‹ˆ๊นŒ.

์ฝ”์–ด๊ฐ€ 2๊ฐœ๊ณ  ๊ณ ๋ฃจํ‹ด์ด 3๊ฐœ๋ฉด 3๋ฒˆ์งธ ๊ณ ๋ฃจํ‹ด์€ ๋Œ€๊ธฐํ•œ๋‹ค. ๊ณ ๋ฃจํ‹ด์ด ํ•˜๋‚˜๊ฐ€ ๋๋‚˜๋ฉด ๊ฑฐ๊ธฐ์— 3๋ฒˆ์งธ์— ๋„ฃ์–ด์ค€๋‹ค.

๋Œ€๊ธฐํ•˜๋Š”๊ฒŒ ๋งŽ์•„์ง€๋ฉด?? ๋ณดํ†ต ๋Œ€๊ธฐ๋ฅผ ๋งŽ์ดํ•œ๋‹ค.

์‹œ์Šคํ…œ ์ฝœ ํ˜ธ์ถœ์‹œ

์‹œ์Šคํ…œ ์ฝœ์ด๋ž€ ์šด์˜์ฒด์ œ๊ฐ€ ์ง€์›ํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ• ๋•Œ๋Š” ๋งํ•ฉ๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ ๋„คํŠธ์›Œํฌ / ํŒŒ์ผ ์ฝ๊ณ  ์“ฐ๊ธฐ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋•Œ ๋Œ€๊ธฐ์ƒํƒœ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. ๊ทธ๋•Œ ๋Œ€๊ธฐ์ค‘์ธ ๊ณ ๋ฃจํ‹ด๊ณผ ๊ต์ฒด๊ฐ€ ๋œ๋‹ค.

์•„๋ฌด๋ฆฌ ๋งŽ์€ ๊ณ ๋ฃจํ‹ด์„ ์ƒ์„ฑํ•ด๋„ OS ๋‹จ์—์„œ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

์‚ฌ์‹ค ๊ณ ๋ฃจํ‹ด์ด ๊ต์ฒด๋˜๋Š”๊ฒƒ๋„ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด๋‹ค. ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ os ์ปจํ…์ŠคํŠธ ๋ณด๋‹ค ์Šคํƒ์ด ์ž‘๋‹ค.

๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ฃผ์˜์ 

๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ž์›์„ ์—ฌ๋Ÿฌ ๊ณ ๋ฃจํ‹ด์—์„œ ์ ‘๊ทผํ• ๋•Œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋ฎคํ…์Šค (์ƒํ˜ธ๋ฐฐ์ œ)๋ฅผ ์ด์šฉํ•œ ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ

๋ฝ์„ ๊ฑธ์–ด์„œ ๋ฉ”๋ชจ๋ฆฌ ์ž์›์„ ํ•˜๋‚˜์˜ ๊ณ ๋ฃจํ‹ด์—์„œ๋งŒ ์ ‘๊ทผํ•˜๊ฒŒ ํ•ด์•ผํ•œ๋‹ค.

์ƒํ˜ธ๋ฐฐ์ œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” Mutex, Semaphore ๋ฐฉ์‹์ด ์‚ฌ์šฉ๋œ๋‹ค. java์—์„œ Synchronized ์ธ๊ฐ€?

defer๋ฅผ ์‚ฌ์šฉ

//ch24/ex24.4/ex24.4.go
package main

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

var mutex sync.Mutex // โถ ํŒจํ‚ค์ง€ ์ „์—ญ ๋ณ€์ˆ˜ ๋ฎคํ…์Šค

type Account struct {
  Balance int
}

func DepositAndWithdraw(account *Account) {
  mutex.Lock()         // โท ๋ฎคํ…์Šค ํš๋“
  defer mutex.Unlock() // โธ defer๋ฅผ ์‚ฌ์šฉํ•œ Unlock()
  if account.Balance < 0 {
    panic(fmt.Sprintf("Balance should 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()
}

๊นƒ๋ฐœ์„ ๊ฝ‚์€ ๋†ˆ์ด ์™•..

crtl+r๋กœ ํ”„๋กœ๊ทธ๋žจ ๊ฐ•์ œ ์ข…๋ฃŒ

๋ฎคํ…์Šค์˜ ๋ฌธ์ œ์ 

  • ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ง์œผ๋กœ ์ธ์ƒ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์–ป์„์ˆ˜ ์—†๋‹ค. ์‹ฌ์ง€์–ด ๊ณผ๋„ํ•œ ๋ฝํ‚น์œผ๋กœ ์„ฑ๋Šฅ์ด ํ•˜๋ฝ๋˜๊ธฐ๋„ ํ•œ๋‹ค.

  • ๊ณ ๋ฃจํ‹ด์„ ์™„์ „ํžˆ ๋ฉˆ์ถ”๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ๋“œ๋ฝ ๋ฌธ์ œ ๋ฐœ์ƒ (์ฒ˜์Œ์—๋Š” ์ž˜ ์•ˆ๋ณด์ž„..๋ฐ๋“œ๋ฝ..)

  • ๋ฐ๋“œ๋ฝ์„ ์ฃผ์˜ํ•ฉ์‹œ๋‹ค.

๋ฎคํ…์Šค ๊ฒฐ๋ก 

  • ๋ฉ€ํ‹ฐ์ฝ”์–ด ์ปดํ“จํ„ฐ์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ณ ๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ•˜์ง€๋งŒ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ณ ๋ฃจํŒ…ใ…‡์ด ์ ‘๊ทผํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๊ผฌ์ผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฎคํ…์Šค๋ฅผ ์ด์šฉํ•˜๋ฉด ๋™์‹œ์— ๊ณ ๋ฃจํ‹ด ํ•˜๋‚˜๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ์กฐ์ •ํ•ด ๊ผฌ์ด๋Š” ๋ฌธ์ œ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

  • ๊ทธ๋Ÿฌ๋‚˜ ๋ฎคํ…์Šค๋ฅผ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅํ–ฅ์ƒ๋„ ๋ฐ๋“œ๋ฝ์ด๋ผ๋Š” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฎคํ…์Šค๋Š” ๋งค์šฐ ์กฐ์‹ฌํžˆ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋Ÿผ ์•„์— ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ฐ€? ๊ทธ๊ฑด ์•„๋‹ˆ๋ผ๊ณ ํ•จ. ๊ฐ€์žฅ ์‹ฌํ”Œํ•˜๊ฒŒ ์‚ฌ์šฉํ• ์ˆ˜ ์ž‡์Œ...๋Œ€์‹  ์กฐ์‹ฌํ•˜์—ฌ...

๋ฎคํ…์Šค๋ฅผ ์“ฐ์ง€ ์•Š์•„์•ผ ํ• ๊นŒ์š”? ๋ฎคํ…์Šค๊ฐ€ ๊ณ ์ด์ง€ ์•Š๋„๋ก ์ข์€ ๋ฒ”์œ„์—์„œ ๋ฐ๋“œ๋ฝ์— ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”์ง€ ์ฒ ์ €ํžˆ ํ™•์ธํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ์ „ํžˆ ์œ ์šฉํ•˜๊ณ  ์†์‰ฌ์šด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋˜๋‹ค๋ฅธ ์ž์› ๊ด€๋ฆฌ ๊ธฐ๋ฒ• (๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ )

  • ์˜์—ญ์„ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ• - ์„œ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด๋จ.

  • ์—ญํ• ์„ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ• - ์ฑ„๋„

Last updated