美文网首页
2023-11-11-并发编程1

2023-11-11-并发编程1

作者: 护念 | 来源:发表于2023-11-10 16:51 被阅读0次

    1. 对并发和并行的一点小认知

    只有多核才有并行。

    2. goroutine哲学:

    通过通信去共享内存,而不是通过共享内存去通信
    这也是go语言和其它语言最大的不同点。

    3. main函数执行启动本质上就是启动了一个goroutine

    4. 主协程和非主协程

    主协程退出后,默认其它的非主协程都会退出;这就像一个boss,死掉后;它的小鬼自动消失;

    5. sync.WaitGroup保证所有协助都执行完再退出。

    默认情况下,主协助执行完后,如果直接退出,那么其它次协程都会消失;那么也就不能正常执行完。

    为了保证所有协程(goroutine)都能正常执行,我们可以通过sync包来保证所有协程都能正常执行。

    1. 在开启一个goruntine前先添加w.Add()
    2. 在gorountine开启的函数内,defer添加 w.Done()保证释放
    3. 主协程中添加w.Wait() 等待所有协程能执行完

    看代码:

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    // 等效于 var w = sync.WaitGroup{} 推荐按照这个写法
    var w sync.WaitGroup
    
    func main() {
        // 迭代字母 注意这里是字符 unicode字符属于rune = int32
        for i := 'A'; i <= 'E'; i++ {
            w.Add(1) // 在开启goroutine前,每增加一个gorotinue 调用一次Add
            go PrintLetters(i)
        }
    
        w.Wait() // 等待所有goroutine执行完
    }
    
    func PrintLetters(ch rune) {
        defer w.Done()          // 每次运行完goroutine 标记一下
        fmt.Printf("%c\n", ch)  // 用c代替字符
        time.Sleep(time.Second) // 模拟耗费时
    }
    

    我们改成goroutine后发现程序执行总时间缩短了,因为并发执行。

    上面的代码的知识点有点多;下面列出来一一说明:

    6. var a xx结构体

    1. var a Person 这种写法,基本上和var a = Person{}等价
    2. 推荐var a = Person{}显示初始化
    3. var a Person之所有效,机理在于go的变量定义会给默认值,比如整数的默认值就是0

    7. 字符的类型为rune = int32

    1. 因为是整数,所以可以执行加法
    // 迭代字母 注意这里是字符 unicode字符属于rune = int32
        for i := 'A'; i <= 'E'; i++ {
            //xxx
        }
    
    1. 打印字符通过%c
    fmt.Printf("%c\n", ch)
    

    8. runtime包runtime.NumCPU()查看机器核心数

    package main
    
    import (
        "fmt"
        "runtime"
    )
    
    func main() {
        fmt.Println(runtime.NumCPU())
    }
    

    9. runtime.GOMAXPROCS()

    GOMAXPROCS用于设置程序运行并行线程数,一般和物理机核心数保持一致就行;从1.5版本开始后,它的默认值就是物理机器核心;不需要手动设置,也不推荐。

    10 .runtime.Gosched 让出当前gorountinue的执行

    它会让出当前gorountine的执行,让其它gorountine执行, 当前gorountine也会执行;只是执行交给了go调度器。

    它有点像一种谦让行为,本该自己执行,却让出,让其它代码先执行;
    这是一种go提供的干预gorountine调度的方式。

    10. runtime.Goexit

    1. 退出当前gorountine
    2. 退出前defere会正常执行的(放心)

    相关文章

      网友评论

          本文标题:2023-11-11-并发编程1

          本文链接:https://www.haomeiwen.com/subject/kvnhwdtx.html