go语言工程进阶之并发编程 | 青训营笔记

85 阅读1分钟

go语言工程进阶之并发编程 | 青训营笔记

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

并发编程

go语言的流行的重要原因之一就是其自带并发编程,那么

并发和并行有什么区别呢?

并行:多线程的程序在cpu的一个核上运行

并发:多线程的程序在cpu的多个核上运行

因此,go语言能充分发挥现代计算机多核心cpu的特点,从而大大提高运行效率

协程 Goroutine和线程是什么关系?

协程:用户态,轻量级线程 栈MB级别

线程:内核态,线程跑多个协程,栈KB级别

线程占用系统资源大,协程的创建和调度都由go语言进行

通俗的说,就是避免多次大量的创建、切换、停止线程占用过多系统资源,改为在已有线程里多次创建调度协程来完成工作

打开协程的hello world:

package concurrence

import (
    "fmt"
    "time"
)

func hello(i int) {
    println("hello goroutine : " + fmt.Sprint(i))
}

func HelloGoRoutine() {
    for i := 0; i < 5; i++ {
        // go关键字作为创建协程的关键字
        go func(j int) {
            hello(j)
        }(i)
    }
    // 保证子协程运行完前主线程不退出
    time.Sleep(time.Second)
}

并发模型CSP(communicating sequential processes)

主打的就是一个叛逆,通过通信来共享内存

缓冲通道Channel

通道是用来传递数据的一个数据结构,可以用于两个协程之间,通过传递一个指定类型的值来同步运行和通讯

操作符<-用于指定通道的方向,实现发送or接收

若未指定方向,则为双向通道

当然还分为

  • 无缓冲通道 make(chan int)

  • 有缓冲通道 make(chan int, 2)

通过两个Channel通道完成数字平方任务案例:

package concurrence

func CalSquare() {
    src := make(chan int)
    dest := make(chan int, 3)
    go func() {
        defer close(src)
        for i := 0; i < 10; i++ {
            src <- i
        }
    }()
    go func() {
        defer close(dest)
        for i := range src {
            dest <- i * i
        }
    }()
    for i := range dest {
        //复杂操作
        println(i)
    }
}