开篇提问

  1. 知道并发,并行,线程,协程概念吗?或者知道大概含义吗?
  2. 有线程为什么还要有协程?区别是什么?
  3. 『进程』通信方式知道几种?有没有超过3种?
  4. golang『协程』通信方式推荐?
  5. 使用并发的目的是为什么?是能帮我们解决什么问题吗?

概念

并发,线程,协程:概念是不可能概念的,google去吧。或者点击这里,查看上一篇文章

  • 并行:一般是指多个CPU实例或者多台机器在『同一时刻』同时执行某个逻辑(方法)

『进程』通信方式

聊聊并发,进程通信方式,go协程简单应用场景-LMLPHP

go协程通讯使用

基本上就是推荐使用channel,这个是最推荐的使用形式;

还有就是使用sync.Mutex互斥锁进行加锁通讯;

更详细的介绍以后写;

go使用协程一些应用场景,简单举例

  1. 进行互不相干的『循环』,需要等待结果计算

这种情况下,一般是不同『数据集合』需要进行『处理』,在处理的过程中两个数据集合对『结果』造成的影响没有时序行

这种情况下,完全可以采用两个数据单独进行协程处理然后再进行后续运算;

// 伪代码
var result, data1, data2 int32
done1 := make(chan bool)
done2 := make(chan bool)
// 第一个数据集合,需要求和
go func() {
    for _, val := range dataset1 {
        data1 += val
    }
    done1 <- true
}

// 第二个数据集合,需要求和
go func() {
    for _, val := range dataset2 {
        data2 += val
    }
    done2 <- true
}

// 等待协程完成运算
<-done1
<-done2

// 结果进行相加
result = data1 + data2
  1. 需要额外进其他不相干的业务,不耽误『主协程』的返回值,不等待

一般有些业务处理以后,有些『额外工作』需要处理但是不耽误主协程返回数据,这个时候就可以开个协程去做,不用等待

// 伪代码

result, err := processMethod()
if err != nil {
    .....
}
// 需要对结果进行写缓存等其他操作,不耽误数据返回
go func() {
    err = saveRedis(result)
    if err != nil {
    	.....
	}
}

return result
  1. 对某些任务进行时间限制,『超时关闭』当前操作

例如,通过管道channel发送某些数据,若超时则自动放弃本次发送,关闭通道。

// 定义两个有缓冲通道,容量分别为1
c1 := make(chan string, 1)
c2 := make(chan string, 1)

go func() {
    time.Sleep(time.Second * 1) // 隔1秒发送数据
    c1 <- "data1"
}()

go func() {
    time.Sleep(time.Second * 6) // 隔6秒发送数据
    c2 <- "data2"
}()

for i := 0; i < 2; i++ {
    // 给通道创建容忍时间,如果5s内无法读写,就即刻返回
    tm := time.NewTimer(time.Second * 5)
    // 使用select来获取这两个通道的值,然后输出
    select {
        case data1 := <-c1:          // 接收c1通道数据(消费数据)
        	fmt.Println(msg1)
        case data2 := <-c2:          // 接收c2通道数据(消费数据)
        	fmt.Println(msg2)
        case <-tm.C:
        	fmt.Println("timeout!")
    }
}

篇末提问

  1. 使用过协程吗?知道协程与线程的区别吗?
  2. 如果是单核CPU,开协程会有用吗?
  3. 本文由于没有帮助你提升code能力?
  4. 进程通讯方式有没有一点点了解?
  5. 你会使用本文的协程案例提升运行速度吗?
01-09 21:16