0%

控制gorutine顺序输出(生产者——消费者)

以此铭记失败的面试

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()
}
-------------本文结束感谢您的阅读-------------
打赏一瓶矿泉水