GO语言多线程实践-3

本文介绍了Go语言中的Channel并发原语在生产者消费者和WaitGroup场景中的应用。通过示例代码展示了如何使用Channel进行数据传递,以及如何替代WaitGroup实现线程同步。强调了理解并谨慎使用Channel的重要性,建议在必要时使用mutex和共享变量解决多线程问题。
摘要由CSDN通过智能技术生成

关于Channel这种GO语言并发原语

其实channel已经在另外一篇博客里面有曾经提到过,其使用起来是阻塞的(非buffered),所以比较容易造成dead lock。今天主要总结其两种比较优秀的应用场景:1.生产者和消费者的场景;2.用于替换WaitGroup的场景。

生产者和消费者的场景

具体代码见下:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	c := make(chan int)
	for i := 0; i < 4; i++ {
		go producer(c)
	}

	for {
		res := <- c
		fmt.Println(res)
	}
}

func producer(c chan int)  {
	for {
		time.Sleep(time.Duration(rand.Intn(1000))* time.Millisecond)
		c <- rand.Int()
	}
}

简而言之,上述代码就是生成了4个随机数生产者,不停地向通道中生产输出随机数,因此也需要不停地从通道中去取数据,不然将会造成死锁。

WaitGroup场景

WaitGroup适用于一组线程协作一起完成某项任务后,一起退出或者继续向下执行的场景。见下:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(x int) {
			sendRpc(x)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func sendRpc(x int)  {
	fmt.Println(x)
}

而上述过程也可以通过利用channel来完美替换实现,见下:

package main

import "fmt"

func main() {
	done := make(chan bool)
	for i := 0; i < 5; i++ {
		go func(x int) {
			sendRpc2(x)
			done <- true
		}(i)
	}

	for i := 0; i < 5; i++ {
		<- done
	}
}

func sendRpc2(x int)  {
	fmt.Println(x)
}

简要总结

channel的适用场景比较典型,但是一般还是不建议使用channel,除非你非常清楚他在干什么,尽量还是多使用mutex以及共享变量来解决多线程的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值