go实战之channel

package good_pratice

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

// UnbufferedChannel 这个方法会出现死锁
// 无缓冲通道说明通道是没有空间的,不能暂存数据,所以必须发送和接收同时发生。要满足”同时发生“这个条件,必须放在不同协程中。
func UnbufferedChannel() {
	c := make(chan int)
	c <- 3
	a := <-c
	fmt.Printf("a:%#v\n", a)
}

//UnbufferedChannel2 正确示例
// 满足接收和发送”同时发生“
func UnbufferedChannel2() {
	c := make(chan int)
	go func() {
		time.Sleep(time.Second * 2)
		c <- 3
	}()
	a := <-c
	fmt.Printf("a:%#v\n", a)
}

// UnbufferedChannel3 for range遍历channel
// 串行执行,并不会同时并发执行
func UnbufferedChannel3() {
	c := make(chan int)

	go func() {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Second) //模拟执行耗时任务
			c <- i
		}
		close(c) // 重点:这里发送完数据后一定要执行close关闭通道,否则打印之后会报死锁。
	}()

	for n := range c {
		fmt.Printf("n:%#v\n", n)
	}
}

//UnbufferedChannel4
//并行执行多个任务
func UnbufferedChannel4() {
	c := make(chan int)

	go func() {
		wg := sync.WaitGroup{}
		for i := 0; i < 100; i++ {
			temp := i
			wg.Add(1)
			go func() {
				defer wg.Done()
				time.Sleep(time.Second) //模拟执行耗时任务
				c <- temp
			}()
		}
		wg.Wait()
		close(c) // 重点:这里发送完数据后一定要执行close关闭通道,否则打印之后会报死锁。
	}()

	for n := range c {
		fmt.Printf("n:%#v\n", n)
	}
}

// bufferedChannel
// 利用有缓冲通道并发执行任务,并且可以限制协程数量
func bufferedChannel() {
	maxConcurrency := 3 // 定义一个最大并发数为3的通道
	concurrency := make(chan struct{}, maxConcurrency)
	// 模拟执行10个任务
	numTasks := 10
	var wg sync.WaitGroup
	for i := 0; i < numTasks; i++ {
		wg.Add(1)
		go func(taskID int) {
			defer wg.Done()
			// 执行任务前获取通道中的令牌
			concurrency <- struct{}{}
			fmt.Printf("开始执行任务:%d\n", taskID)
			// 模拟任务执行时间
			time.Sleep(time.Second * 2)
			fmt.Printf("完成任务:%d\n", taskID)
			// 任务完成后释放通道中的令牌
			<-concurrency
		}(i)
	}
	// 等待所有任务完成
	wg.Wait()
}

func ChannelTest() {
	//UnbufferedChannel()  //这个方法会报错:fatal error: all goroutines are asleep - deadlock!
	//UnbufferedChannel2() //这个方法正确
	//UnbufferedChannel3() //能够正常输出通道的数据,不过是串行执行,并不会同时并发执行。即每秒输出一个数字。100个数字耗时100秒。
	//UnbufferedChannel4() //这个不仅能正常输出通道的数据,而且是并行执行,同时开100个协程执行任务,一秒内就能完成任务。不过输出的是乱序。

	bufferedChannel() //有缓冲通道并发执行,还能控制协程的数量
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值