golang ---------- channel 通道(二 等待任务结束)

1、一个任务结束后,才执行下一个任务

type channell struct {
	in chan int
	done chan bool
}

func workGo(id int,c chan int,done chan bool) {
	for a := range c{
		fmt.Printf("work %d received %d\n",id,a)
		done <- true
	}
}

func work(id int) channell {
	c := channell{              //通过通道共享内存
		in: make(chan int),
		done: make(chan bool),
	}
	go workGo(id,c.in,c.done)
	return c
}

func chanMake(){
	var channels [9]channell
	for i:=0;i<9;i++ {
		channels[i] = work(i)
	}

	for i:=0;i<9;i++ {  //一共9个任务
		channels[i].in <- i
		<-channels[i].done  //发一个任务等着这个任务结束,才执行下一个任务
	}
}

func main(){
	chanMake()
	time.Sleep(time.Millisecond)
}

2、等待所有的任务都完成

type channell struct {
	in chan int
	done chan bool
}

func work(id int,c chan int,done chan bool) {
	for a := range c{        //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
		fmt.Printf("channe %d received %d\n",id,a)
		go func(){
			done <- true
		}()
	}
}
func workGo(id int) channell {
	c := channell{              //通过通道共享内存
		in: make(chan int),
		done: make(chan bool),
	}
	go work(id,c.in,c.done)     //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
	return c
}
func chanMake(){
	var channels [9]channell
	for i:=0;i<9;i++ {
		channels[i] = workGo(i)
	}
	for i:=0;i<9;i++ {
		channels[i].in <- i    //现在c.in通道里有数据了,work里面需要数据的地方可以工作了,所以是通过通道共享内存,共享了i
	}
	for i:=0;i<9;i++ {
		channels[i].in <- i + 'a'
	}
	for _,channell := range channels{ //等所有的任务都结束
		<-channell.done
		<-channell.done
	}
}

func main(){
	chanMake()
}

3、使用sync.WaitGroup等待所有任务完成

sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行。

type channell struct {
	in chan int
	wg *sync.WaitGroup
}

func work(id int,c chan int,wg *sync.WaitGroup) {
	for a := range c{        //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
		fmt.Printf("channe %d received %d\n",id,a)
		wg.Done()
	}
}
func workGo(id int,wg *sync.WaitGroup) channell {
	c := channell{              //通过通道共享内存
		in: make(chan int),
		wg: wg,
	}
	go work(id,c.in,wg)     //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
	return c
}
func chanMake(){
	var wg sync.WaitGroup

	var channels [9]channell
	for i:=0;i<9;i++ {
		channels[i] = workGo(i,&wg)
	}

	wg.Add(18)      //加进去18个任务
	for i:=0;i<9;i++ {
		channels[i].in <- i    //现在c.in通道里有数据了,work里面需要数据的地方可以工作了,所以是通过通道共享内存,共享了i
	}
	for i:=0;i<9;i++ {
		channels[i].in <- i + 'a'
	}
	wg.Wait()         //等待这20个任务做完
}

func main(){
	chanMake()
}

将wg.Done包装一下:

func work(id int,c channell) {
	for a := range c.in{        //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
		fmt.Printf("channe %d received %d\n",id,a)
		c.done()
	}
}
func workGo(id int,wg *sync.WaitGroup) channell {
	c := channell{              //通过通道共享内存
		in: make(chan int),
		done: func(){
			wg.Done()
		},
	}
	go work(id,c)     //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
	return c
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值