package main

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

func main() {
	var wg sync.WaitGroup
	//一个没有缓冲区的chan
	ch := make(chan string)
	wg.Add(3)
	go sendData(ch, &wg)
	go getData(ch, &wg)
	go getData2(ch, &wg)

	// 等待所有的goroutine都执行完成后才关闭主线程
	time.Sleep(time.Second*3)
	wg.Wait()
	fmt.Printf("main goroutine exited\n")
}

// 如果定义的不是全局的wait group,则在传值的时候需要传指针类型
func sendData(ch chan string, waitGroup *sync.WaitGroup) {
	ch <- "aaa"
	ch <- "bbb"
	ch <- "ccc"
	ch <- "ddd"
	ch <- "eee"

	// 关闭chan,即使使用了 waitGroup也需要关闭channel
	// waitGroup只是用于主线程等待goroutine执行完毕
	// channel是一个队列,用于多个goroutine的通讯
	close(ch)
	fmt.Printf("send data exited")
	// 使用 waitGroup给出goroutine的结束信号
	waitGroup.Done()
}

//
func getData(ch chan string, waitGroup *sync.WaitGroup) {
	for {
		input, ok := <-ch
		if !ok {
			break
		}
		fmt.Printf("getData中的input值: %s\n", input)
	}
	fmt.Printf("get data exited\n")
	// 使用 waitGroup给出goroutine的结束信号
	waitGroup.Done()
}

func getData2(ch chan string, waitGroup *sync.WaitGroup) {
	for {
		input2, ok := <-ch
		if !ok {
			break
		}
		fmt.Printf("getData2中的input值:%s\n", input2)
	}
	fmt.Printf("get data2 exited\n")
	// 使用 waitGroup给出goroutine的结束信号
	waitGroup.Done()
}