Go并发相关

175 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

三、并发相关

1. 基础

并发:电脑同时听歌,看小说,看电影。cpu根据时间片进行划分,交替执行这个三个程序。我们人可以感觉是同时产生的。

并行:多个CPU(多核)同时执行

c语言里面实现并发过程使用的是多线程(C++的最小资源单元),进程

go语言里面不是线程,而是go程 ==> goroutine,go程是go语言原生支持的

每一个go程占用的系统资源远远小于线程,一个go程大约需要4K~5K的内存资源

一个程序可以启动大量的go程:

  • 线程 ==》几十个
  • go程可以启动成百上千个, ===》 对于实现高并发,性能非常好
  • 只需要在目标函数前加上go关键字即可
package main
​
import (
    "fmt"
    "time"
)
​
//这个将用于子go程使用
func display() {
    count := 1
    for {
        fmt.Println("=============> 这是子go程:", count)
        count++
        time.Sleep(1 * time.Second)
    }
}
​
func main() {
    //启动子go程
    //go display()
    go func() {
        count := 1
        for {
            fmt.Println("=============> 这是子go程:", count)
            count++
            time.Sleep(1 * time.Second)
        }
    }()
​
    //主go程
    count := 1
    for {
        fmt.Println("这是主go程:", count)
        count++
        time.Sleep(1 * time.Second)
    }
}
​

启动多个字go程,他们会竞争cpu资源

package main
​
import (
    "fmt"
    "time"
)
​
//这个将用于子go程使用
func display(num int) {
    count := 1
    for {
        fmt.Println("=============> 这是子go程:", num, "当前count值:", count)
        count++
        //time.Sleep(1 * time.Second)
    }
}
​
func main() {
    //启动子go程
    for i := 0; i < 3; i++ {
        go display(i)
    }
​
    //go func() {
    //  count := 1
    //  for {
    //      fmt.Println("=============> 这是子go程:", count)
    //      count++
    //      time.Sleep(1 * time.Second)
    //  }
    //}()//主go程
    count := 1
    for {
        fmt.Println("这是主go程:", count)
        count++
        time.Sleep(1 * time.Second)
    }
}
​

2. 提前退出go程

  • return ===> 返回当前函数
  • exit ===> 退出当前进程
  • GOEXIT ===> 提前退出当前go程
package main
​
import (
    "fmt"
    "runtime"
    "time"
)

​
func main() {
    go func() {
        go func() {
            func() {
                fmt.Println("这是子go程内部的函数!")
                //return //这是返回当前函数
                //os.Exit(-1) //退出进程
                runtime.Goexit() //退出当前go程
            }()
​
            fmt.Println("子go程结束!") //这句会打印吗? 会1:  不打印2
            fmt.Println("go 2222222222 ")
​
        }()
        time.Sleep(2 * time.Second)
        fmt.Println("go 111111111111111")
    }()
​
    fmt.Println("这是主go程!")
    time.Sleep(3 * time.Second)
    fmt.Println("OVER!")
}
​