Go语言并行和并发 | 青训营笔记

77 阅读2分钟

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

  • 并发(concurrency):把任务在不同的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。
  • 并行(parallelism):把每一个任务分配给每一个处理器独立完成。在同一时间点,任务一定是同时运行。

并发和并行的区别:

并发(concurrent)指的是多个程序可以同时运行的现象,更细化的是多进程可以同时运行或者多指令可以同时运行。但这不是重点,在描述并发的时候也不会去扣这种字眼是否精确,并发的重点在于它是一种现象。并发描述的是多进程同时运行的现象。但实际上,对于单核心CPU来说,同一时刻只能运行一个进程。所以,这里的"同时运行"表示的不是真的同一时刻有多个进程运行的现象,这是并行的概念,而是提供一种功能让用户看来多个程序同时运行起来了,但实际上这些程序中的进程不是一直霸占CPU的,而是执行一会停一会。

GO语言实现并行和并发:

并发是单核在处理,例如ABCD四个任务,单核心会不断在这四个任务之间切换,肉眼看四个任务都在执行,但实际只有一个任务在执行,切换都是微秒,所以宏观上是都在执行,微观就只有一个任务在执行。

并行是多核在处理,例如ABCD四个任务,每个任务都有一个单独的核在处理,不用来回切换,都在自己干自己的,一块向前行,就是并行。

go天生支持并发,像java等语言,并发时都是交给操作系统去分配,而在go中,go内置实现了任务的调度和管理。

go中的并发由goroutine实现,类似于线程。创建goroutine只需要在函数前加一个go关键字,当我们需要并发时,只需要把任务写到函数中,然后使用go关键字开启一个goroutine去执行即可。

并发:

package main

import (
    "fmt"
)

func loop(done chan bool) {
    for i := 0; i < 10; i++ {
        fmt.Print(i)
    }
    done <- true
}

func main() {
    done := make(chan bool)
    go loop(done)
    go loop(done)

    <-done
    <-done

}

并发:

package main

import (
    "fmt"
    "runtime"
)

func loop(done chan bool) {
    for i := 0; i < 100; i++ {
        fmt.Printf("%d ", i)
    }
    done <- true
}

func main() {
    runtime.GOMAXPROCS(2)
    done := make(chan bool)
    go loop(done)
    go loop(done)

    <-done
    <-done

}


package main

import (
    "fmt"
    "runtime"
)

func loop(done chan bool) {
    for i := 0; i < 100; i++ {
        fmt.Printf("%d ", i)
        runtime.Gosched()  //// 显式地让出CPU时间给其他goroutine
    }
    done <- true
}

func main() {
    // runtime.GOMAXPROCS(2)
    done := make(chan bool)
    go loop(done)
    go loop(done)

    <-done
    <-done

}