(๐ญGo) Goroutine
ํ๋ง๋ฒ์ฌ๊ฐ ๋์ด๋ณด์
๋๋์ด Golang์ ๋ฐฐ์ฐ๋ ๊ฐ์ฅ ํฐ ์ด์ ์ธ ๊ณ ๋ฃจํด(Goroutine) ์๊ฐ์ด๋ค.
ํ๋ฒ ์ฌ์ฉํด๋ณด์
func sexyCount(person string) {
for i := 0; i < 10; i++ {
fmt.Println(person, "is sexy", i)
time.Sleep(time.Second)
}
}
func main() {
go sexyCount("nico")
sexyCount("flynn")
}
๋ ๋ฒ์ sexyCount ํธ์ถ์ด ์๋๋ฐ ๋์์ ์คํ์ด ๋๋ค. go๋ง ์์ ๋ถ์ด๋ฉด concurrenncyํ๊ฒ ๋์๊ฐ๋ ๊ฒ์ด๋ค.
๊ณจ๋๋ฆฐ๋ค ์ ๋งโฆ
func main() {
go sexyCount("nico")
go sexyCount("flynn")
}
์ด๋ ๊ฒ ํ๋ฉด? ์๋ฌด์ถ๋ ฅ ์์ด ํ๋ก๊ทธ๋จ์ด ๋๋๋ฒ๋ฆฐ๋ค.
mainํจ์๋ goroutine์ ๊ธฐ๋ค๋ฆฌ์ง ์๋๋ค!
์ด์ฐ๋์๊ฑด ์ ์ฒด ํ๋ฆ์ ์์ด์ผํ๋ ๊ฒ์ด๋ค.
go sexyCount("nico")
go sexyCount("flynn")
time.Sleep(time.Second * 5)
์ด๋ฐ์์ผ๋ก sleep์ ํด๋ณด๋ฉด ์๋์๊ฐ๋ค.
Channel
๋ค์์ Channel๊ฐ๋
์ด๋ค. channel
์ goroutine
๊ณผ main ํจ์
์ฌ์ด์ ์ ๋ณด๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ด๋ค. ๊ฒฐ๊ตญ ๋ฉํฐ์ฝ์ด๋ก ๋ฉํฐ์ฐ๋ ๋๋ฅผ ๋๋ฆฐ๋ค๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ทจํฉํ๋ ์ผ์ด ์๊ธฐ๊ฒ ๋์ด ์๋ค. ๊ทธ๋ด ๋๋ฅผ ์ํด ์กด์ฌํ๋ ๊ฒ์ด ์ฑ๋์ด๋ค.
ํน์ goroutine
๊ณผ goroutine
์ฌ์ด์ ํต์ ์ ์ํด์๋ ์ฐ์ผ ์ ์๋ค. ๋ณดํต์ ๋ฉํฐ์ฐ๋ ๋ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ๊ณ ์๊ฐํ๋ค๋ฉด ์ด๋ฐ์ผ์ ํ๊ธฐ์ํด ์์ฃผ ํฐ ๋
ธ๋ ฅ์ด ๋ค๊ฒ์ด๋ค. (C++๋ก ํ๋ค๊ณ ์๊ฐ์ ํด๋ณด์โฆ)
func main() {
c := make(chan bool) // 1. ์ฑ๋์ ๋ง๋ ๋ค c๋ ์ฑ๋์ ์ด๋ฆ์ด๋ค
people := [2]string{"nico", "flynn"}
for _, person := range people {
go isSexy(person, c) // 2. ๊ณ ๋ฃจํด์ ์ธ์๋ก ์ฑ๋์ ๋๊ฒจ์ค๋ค
}
fmt.Println(<-c) // 5. <- ์ฐ์ฐ์๋ก ์ฑ๋๋ก๋ถํฐ ๊ฐ์ ๋ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์๋๊น์ง ๋๊ธฐํ๋ค. sleep ํ์์๋ค.
fmt.Println(<-c) // <-๋ฅผ ์ฐ๋ฉด ์ด ๋ฌธ์ฅ์ ๋ธ๋กํน์ฐ์ฐ์ด ๋๋ค.
fmt.Println(<-c) // ๊ณ ๋ฃจํด์ ๋๊ฐ๊ฐ ๋๋๋ฐ 3๊ฐ์ ์ฑ๋์ ๊ธฐ๋ค๋ฆฌ๋ฏ๋ก ๋ฐ๋๋ฝ์ผ๋ก ํ๋ก๊ทธ๋จ์ด ์ฃฝ๋๋ค.
}
func isSexy(person string, c chan bool) { // 3. ์ฑ๋์ ๋ฐ์ ์ ์๋๋ก ํ๋ผ๋ฉํฐ๋ฅผ ์ถ๊ฐํ๋ค
time.Sleep(time.Second * 5)
fmt.Println(person)
c <- true // 4. ์ฑ๋๋ก ๊ฐ์ ์ค๋ค. ๋ฆฌํด๊ฐ์ ๊ฐ๋
์ด๋ค.
}
result := <-c;
:= <-
๋ผ๋โฆ๋ญ๊ฐ ๊ณ ๋๋ฌธ์์ค๋ฝ์ง๋ง ์ ๊ฒ์ด ๊ฒฐ๊ณผ๋ฅผ ์ทจํฉ๋ฐ๊ธฐ ์ํ ์ฝ๋์ด๋ค. ๊ธฐ๊ดดํ๋ค๊ณ ์๊ฐํ์ง๋ง๊ณ ๊ท์ฝ๋ค๊ณ ์๊ฐ์ ํด๋ณด์(โฆ)
func hitURL(url string, c chan<- result)
์ฌ๊ธฐ์ chan<-
์ด ์๋ฏธ๋ ์ฑ๋์ ํตํ sendOnly๋ผ๋ ๋ป์ด๋ค. hitURL์์๋ ์ฑ๋์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์๋ ์๋ค. ํ์ดํ๊ฐ ์ค๋ฅธ์ชฝ์ธ์ง ์ผ์ชฝ์ธ์ง๋ฅผ ๊ตฌ๋ถํ์.