CPU基本概念

要了解golang的并发编程,需要先简单了解cpu是什么?

cpu是计算机的“大脑”,不仅能实现基本算术运算,还能通过总线控制和协调电子配件的输入和输出。我们编写的程序代码,比如打印语句,最终是由cpu从内存中取得指令、解码、执行。cpu执行指令速度非常快,通常执行一条指令只需要零点几纳秒。

早期的计算机是单核的,计算机设计师在设计体系结构为了能让处理器跑得更快,把cpu设计为交替地取得和执行指令。简单地说就是运行中的程序在极短时间内都能通过cpu执行部分指令,这样来回交替使其它程序的指令有机会得到解决,而不是一个程序的所有指令都执行完了,再执行另一个程序的指令。

而现在计算机有多个cpu,能同时执行多条互不干扰、互不依赖的指令。

golang实现并发

根据cpu核数和执行指令方式,分别引出了并发和并行两个概念。

并发:交替做不同事情的能力。

并行:同时做不同事情的能力。

现在计算机都是多核的,很多高级语言设计者会考虑使用并发 + 并行模式来运行代码。比如golang使用go关键字就能开辟一个协程来执行另外的代码,协程并发可以成千上万,cpu可以充分利用起来,占用资源也很小,这个也是golang流行的原因之一。

通过小小一个例子展示golang并发编程的强大。

计算斐波那契数列是很耗时的过程,如果输入一个较大的数字,用户需要等待一段时间才有结果,此时如果通过另外一个协程显示忙碌状态,用户体验会比较好。

func main() {
    go spinner(100 * time.Microsecond) // 启动一个协程,当前进程有两个协程并发执行
    const n = 45
    fibN := fib(n)
    fmt.Printf("\r斐波那契数列(%d) = %d", n, fibN)
}

// 显示忙碌状态
func spinner(delay time.Duration) {
    for {
        for _, v := range `-\|/` {
            fmt.Printf("\r%c", v)
            time.Sleep(delay)
        }
    }
}

// 计算斐波那契数列
func fib(x int) int {
    if x < 2 {
        return x
    }
    return fib(x - 1) + fib(x - 2)
}