Server/Go
Go) 동시작업 Goroutines
Juzdalua
2022. 11. 23. 16:18
Go는 다른 언어와 마찬가지로 Top-Down 방식으로 동기화처럼 작업이 끝나고 다음 코드를 수행한다.
package main
import (
"fmt"
"time"
)
func main() {
countName("jun")
countName("JUN")
}
func countName(name string) {
for i := 0; i < 5; i++ {
fmt.Println(name)
time.Sleep(time.Second * 1)
}
}
위처럼 수행하면 코드 1줄 당 1초, 총 10초가 걸린다.
Go는 비동기화처럼 동시작업을 위해 사용하는 언어라고 알고있다.
JS의 async/await처럼 Go에서도 go라는 명령어로 비슷하게 작업을 수행할 수 있다.
package main
import (
"fmt"
"time"
)
func main() {
go countName("jun")
countName("JUN")
}
func countName(name string) {
for i := 0; i < 5; i++ {
fmt.Println(name)
time.Sleep(time.Second * 1)
}
}
Goroutine은 메인 함수가 종료되면 함께 종료된다.
다시 말해, 프로그램이 실행 되는 동안에만 유효하다.
Goroutine은 리턴을 반환하지 않는다.
package main
import (
"fmt"
"time"
)
func main() {
go countName("jun")
result := go countName("JUN")
fmt.Println(result)
}
func countName(name string) bool {
time.Sleep(time.Second * 5)
return true
}
위와 같은 코드에서 result := go countName()에 에러가 발생한다.
이를 해결하기 위해 채널을 사용한다.
package main
import (
"fmt"
"time"
)
func main() {
// start immediately
c := make(chan bool)
go countName("JUN", c)
// go runtime is stop. wait until get channel message
result := <-c
fmt.Println(result)
}
func countName(name string, c chan bool) {
time.Sleep(time.Second * 1)
c <- true
}
메인에서 channel을 만든다.
countName 함수에 값을 받을 채널을 함께 파라미터로 보낸다.
countName 함수에서 채널에 결과값을 저장한다.
메인에서 채널 메세지를 받아온다.
채널메세지가 여러개일 경우 Go는 인식한다.
package main
import (
"fmt"
"time"
)
func main() {
// start immediately
c := make(chan bool)
people := []string{"jun", "JUN"}
for _, person := range people {
go countName(person, c)
}
// go runtime is stop. wait until get channel message
fmt.Println(<-c)
fmt.Println(<-c)
}
func countName(name string, c chan bool) {
time.Sleep(time.Second * 5)
c <- true
}
채널을 받는 함수에서는 변수명 chan 채널의리턴타입을 파라미터로 받는다.
채널에 값을 저장하고 채널 메세지를 불러올 때는 <- 연산자를 사용한다.
메인에서 채널 값을 받아올 때는 해당 값을 불러올 때까지 메인함수는 기다려준다.