동시성을 구현할 때 다른 언어의 스레드 등의 방식과는 차별화된 방법
wg := new(sync.WaitGroup)
wg.Add(1)
wg.Done()
wg.Wait()
func main() {
wg := new(sync.WaitGroup)
for i := 0; i < 100; i++ {
// 고루틴 추가
wg.Add(1)
go func(n int) {
fmt.Println("WaitGroup : ", n)
wg.Done()
}(i)
}
// Add로 입력한 고루틴의 수와 == Done() 호출한 횟수가 같아야 한다.
// 끝날때까지 대기
wg.Wait()
fmt.Println("WaitGroup End!")
}
var cnt int64 = 0
wg := new(sync.WaitGroup)
for i := 0; i < 5000; i++ {
wg.Add(1)
go func(n int) {
cnt += 1
// atomic.AddInt64(&cnt, 1)
wg.Done()
}(i)
}
for i := 0; i < 2000; i++ {
wg.Add(1)
go func(n int) {
cnt -= 1
// atomic.AddInt64(&cnt, -1)
wg.Done()
}(i)
}
// 끝날때까지 대기
wg.Wait()
fmt.Println("WaitGroup End! >>>>> ", cnt)
// finalCnt := atomic.LoadInt64(&cnt)
// fmt.Println("WaitGroup End! >>>>> ", finalCnt)
고루틴이라는 동시에 실행되는 함수들 사이에서 데이터를 주고 받거나 흐름제어를 하기 위해서 채널을 사용
ch := make(chan int) // int형 값을 전달할 수 있는 채널 생성
// ...
ch <- 1 // 1을 채널로 전송
var temp int = <-ch // 채널로 받은 값은 수신
func work1(v chan int) {
time.Sleep(1 * time.Second)
v <- 1 // 1을 채널로 전송(송신)
}
func main() {
v := make(chan int) // int형 채널 선언
go work1(v)
fmt.Println(<-v)
// time.Sleep() 를 사용할 필요가 없다.
}
select 문은 switch와 유사한 문법 사용, case에 채널이 사용된다는 점이 차이
ch1 := make(chan int)
ch2 := make(chan string)
go func() {
for {
ch1 <- 77
time.Sleep(250 * time.Millisecond)
}
}()
go func() {
for {
ch2 <- "Golang H!i"
time.Sleep(500 * time.Millisecond)
}
}()
go func() {
for {
select {
case num := <-ch1:
fmt.Println("ch1: ", num)
case str := <-ch2:
fmt.Println("ch2: ", str)
//default:
//
}
}
}()