以此铭记失败的面试
go协程开启后是并发执行且无序的;开启100个协程如何对其进行顺序执行?
第一种方式
package main
import (
"fmt"
"sync"
)
//控制数量
var wg sync.WaitGroup
func producter(out <-chan int, in chan<- int) {
//阻塞 如果out没有值就一直阻塞
key := <-out
fmt.Println("生产:", key)
//输入消费管道
in <- key
wg.Done()
}
func consumer(in <-chan int) {
for v := range in {
fmt.Println("消费:", v)
}
wg.Done()
}
func main() {
//需要消费的缓冲管道
in := make(chan int, 100)
for i := 0; i < 100; i++ {
//生产管道
ch := make(chan int)
wg.Add(1)
//开启生产协程
go producter(ch, in)
//将i顺序输入管道
ch <- i
//当前协程销毁才能进行下一个
wg.Wait()
}
//关闭in通道 不然会出错
close(in)
wg.Add(1)
go consumer(in)
wg.Wait()
}
下一步计划,尽量熟悉go语言协程开发,不要只停留于理论!吸取教训!
第二种方式
package main
import (
"fmt"
"sync"
)
//实现有缓冲区与无缓冲区 消费者生产者
var myCh = make(chan int, 100)
var exitCh = make(chan bool, 1)
var wg sync.WaitGroup
func producter(zhu chan int) {
num := <-zhu
fmt.Println("生产了:", num)
myCh <- num
wg.Done()
}
func consumer() {
for {
if num, ok := <-myCh; !ok {
break
} else {
fmt.Println("消费了:", num)
}
}
fmt.Println("停止消费")
wg.Done()
exitCh <- true
}
func main() {
for i := 0; i < 100; i++ {
zhu := make(chan int)
wg.Add(1)
go producter(zhu)
zhu <- i
wg.Wait()
close(zhu)
}
//wg.Wait()
close(myCh)
wg.Add(1)
go consumer()
//wg.Wait()
fmt.Println("exitCh前")
<-exitCh
fmt.Println("exitCh后")
wg.Wait()
}