西河刘卡车医 发表于 2024-3-24 13:48:17

golang 并发

Golang 并发


[*]并行 指的是在同一时刻 有多条指令在多个CPU处理器上同时执行 2个任务2个窗口需要硬件支持
[*]并发是指在同一时刻 只能有一条指令 单多个进程指令快速轮换执行 2个队伍1个窗口 要求提升软件能力
Golang 并发优势


[*]go 从底层就支持并发
[*]简化了并发程序的编写方法
Goroutine 是什么


[*]它是go 并发设计的核心
[*]goroutine就是协程,它比线程更小,十几个goroutine 在底层可能就是五六个线程
[*]go 语言内部实现了goroutine的内存共享,执行goroutine只需极少的栈内存(大概4-5KB)
创建goroutine


[*]只需要在语句前添加go 关键字即可
    package main

    import (
    "fmt"
    "time"
    )

    //测试协程
    //循环打印内容
    func newTask() {
    i := 0
    for {
    i++
    fmt.Printf("new goroutine\:i=%d\n", i)
    time.Sleep(1 \* time.Second)
    }
    }

    //main()相当于是主协程
    func main() {
    //启动子协程
    go newTask()
    i := 0
    for {
    i++
    fmt.Printf("main goroutine\:i=%d\n", i)
    time.Sleep(1 \* time.Second)
    }
    }

[*]开发人员无需了解任何执行细节,调度器会自动将其安排到合适的系统线程上运行
[*]如果主协程推出,所有子进程协程都会退出
    package main
    import (
    "fmt"
    "time"
    )
    //main()相当于是主协程
    func main() {
    //匿名子协程
    go func() {
      i := 0
      for {
      i++
      fmt.Println("子协程 i=", i)
      time.Sleep(1 \* time.Second)
      }
    }()
    i := 0
    for {
      i++
      fmt.Println("主协程 i=", i)
      time.Sleep(1 \* time.Second)
      //主协程第二次后退出
      if i == 2 {
      break
      }
    }
    }

[*]程序没任何输出,也不报错
    package main

    import (
    "fmt"
    "time"
    )

    //main()相当于是主协程
    func main() {
    //匿名子协程
    go func() {
    i := 0
    for {
    i++
    fmt.Println("子协程 i=", i)
    time.Sleep(1 \* time.Second)
    }
    }()
    }runtime 包


[*]runtime.Gosched(): 用于让出CPU时间片,调度器重新安排任务调度,还是有几率分配到它的
    package main

    import (
    "fmt"
    "runtime"
    )

    func main() {
    //匿名子协程
    go func(s string) {
    for i := 0; i < 2; i++ {
    fmt.Println(s)
    }
    }("world")
    //主协程
    for i := 0; i < 2; i++ {
    runtime.Gosched()
    fmt.Println("hello")
    }
    }

[*]runtime.Goexit() 立即终止当前协程
    package main

    import (
    "fmt"
    "time"
    "runtime"
    )

    func main() {
    //匿名子协程
    go func() {
    defer fmt.Println("A.defer")
    //匿名函数
    func() {
    defer fmt.Println("B.defer")
    //此时只有defer执行
    runtime.Goexit()
    fmt.Println("B")
    }()
    fmt.Println("A")
    }()
    for {
    time.Sleep(time.Second)
    }
    }

[*]runtime.GOMAXPROCS(): 设置并行计算的CPU核数,返回之前的值
    package main

    import (
    "runtime"
    "fmt"
    )

    func main() {
    n := runtime.GOMAXPROCS(3)
    fmt.Println("n=%d\n",n)
    //循环执行2个
    for{
    go fmt.Print(0)
    fmt.Print(1)
    }
    }channel


[*]goroutine运行在相同的地址空间,因此访问共享内存必须做好同步,处理好线程安全
[*]goroutine奉行通过通信来共享内存,而不是共享内存通信
[*]channel 是一个引用类型 用于多个goroutine 通讯 其内部实现了同步,确保并发安全
Channel基本使用

<ul>Channel 可以用内置make() 创建
定义一个channel 也需要定义发送到channel值类型
make(chan 类型) // 无缓冲通道
make(chan 类型, 容量) // 有缓冲通道当capacity=0 时, channel 是无缓冲阻塞读写的,当capacity>0, channel 有缓冲,是非阻塞的,直到写满capacity个元素才阻塞写入
channel 通过操作符
页: [1]
查看完整版本: golang 并发