GO语言使用之channel(管道)

本文深入探讨了Go语言中的channel,解释了为何需要channel来解决并发问题,详细介绍了channel的基础知识,包括其线程安全的特性、类型限制及初始化。通过实例展示了channel的创建、关闭和遍历,以及在goroutine中的应用和最佳实践。同时,文章还讨论了channel的使用细节,如只读/只写channel和避免阻塞的select语句,以及如何在goroutine中使用recover处理panic。
摘要由CSDN通过智能技术生成

一、为什么需要channel

1、需求:
现在要计算 1-200 的各个数的阶乘,并且把各个数的阶乘放入到map中。最后显示出来。要求使用goroutine完成

1)、分析思路:
使用goroutine 来完成,效率高,但是会出现并发/并行安全问题.
这里就提出了不同goroutine如何通信的问题

2)、代码实现
使用goroutine来完成(看看使用gorotine并发完成会出现什么问题? 然后我们会去解决)
在运行某个程序时,如何知道是否存在资源竞争问题。 方法很简单,在编译该程序时,增加一个参数 -race即可
3)、示意图
这里写图片描述
4)、代码实现:

package utils


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

// 需求:现在要计算 1-200 的各个数的阶乘,并且把各个数的阶乘放入到map中。
// 最后显示出来。要求使用goroutine完成 

// 思路
// 1. 编写一个函数,来计算各个数的阶乘,并放入到 map中.
// 2. 我们启动的协程多个,统计的将结果放入到 map中
// 3. map 应该做出一个全局的.

var (
    myMap = make(map[int]int, 10)
)

// cacluFactorial 函数就是计算 n!, 让将这个结果放入到 myMap
func cacluFactorial(n int) {

    res := 1
    for i := 1; i <= n; i++ {
        res *= i
    }




    //这里我们将 res 放入到myMap
    myMap[n] = res //concurrent map writes?



}

func FactorialDemo() {

    // 我们这里开启多个协程完成这个任务[200个]
    for i := 1; i <= 200; i++ {
        go cacluFactorial(i)
    }


    //休眠10秒钟【第二个问题 】
    time.Sleep(time.Second * 10)



    //这里我们输出结果,变量这个结果
    for i, v := range myMap {
        fmt.Printf("map[%d]=%d\n", i, v)
    }



}

2、不同goroutine之间如何通讯

  • 全局变量的互斥锁
  • 使用管道channel来解决

3、使用全局变量加锁同步改进程序
因为没有对全局变量 m 加锁,因此会出现资源争夺问题,代码会出现错误,提示concurrent map writes
解决方案:加入互斥锁
我们的数的阶乘很大,结果会越界,可以将求阶乘改成 sum += uint64(i)
代码改进

package utils


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

// 需求:现在要计算 1-200 的各个数的阶乘,并且把各个数的阶乘放入到map中。
// 最后显示出来。要求使用goroutine完成 

// 思路
// 1. 编写一个函数,来计算各个数的阶乘,并放入到 map中.
// 2. 我们启动的协程多个,统计的将结果放入到 map中
// 3. map 应该做出一个全局的.

var (
    myMap = make(map[int]int, 10)

    /*同步锁改进代码*/
    //声明一个全局互斥锁
    lock sync.Mutex //sync包提供了基本的同步基元,如互斥锁。Mutex是一个互斥锁࿰
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值