欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

go语言实战读书笔记之 goroutine

程序员文章站 2022-07-14 20:53:09
...

go语言并发: 能让某个函数独立于其他函数运行的能力

当一个函数创建为goroutine时,go将它视为一个独立的工作单元,这个工作单元会被调度到可用的逻辑处理器上执行

go语言运行时调度器: 能管理被创建的所有goroutine并为其分配执行时间,
调度器在操作系统之上,将操作系统的线程和语言运行时的逻辑处理器绑定,并在逻辑处理器上运行goroutine

go语言的并发同步模型: 叫通信顺序进程(communicating Sequential Processes)CSP的范性,CSP是一种消息传递模型,通过在goroutine之间传递数据来传递消息,而不是对数据进行加锁来实现同步访问.
用于在goroutine之间同步和传递数据的关键数据类型叫做通道(channel)

并行: 是让不同的代码片段同时在不同的物理处理器上执行,关键是同时做很多事情

并发: 是指同时管理很多事情,这些事情可能只做了一半就被暂停去做别的事情

下图是一个逻辑处理器上并发运行goroutine和两个逻辑处理器上并行运行两个并发的goroutine
go语言实战读书笔记之 goroutine

进程: 包含了应用程序运行需要用到和维护的各种资源的容器,这些资源包括但不限于内存地址空间,文件和设备的句柄以及线程
go语言实战读书笔记之 goroutine

线程:一个执行空间,这个空间被操作系统调度来运行函数中所写的代码

每个进程至少包含一个线程

操作系统会在物理处理器上调度线程来运行
go语言运行时会在逻辑处理器上调度goroutine来运行
每个逻辑处理器都分别绑定在单个操作系统线程上

如果创建一个goroutine并准备运行:
这个goroutine就会被放在调度器的全局运行队列中;
调度器就将这些队列中的goroutine分配一个逻辑处理器,并放在这个逻辑处理对应的本地运行队列中;
本地运行队列中goroutine一直等待自己被分配到逻辑处理器上执行

正在运行的goroutine执行一个阻塞的系统调用:
线程和goroutine会从逻辑处理器上分离;
该线程继续阻塞等待系统调用的返回;
这个逻辑处理器就失去了运行的线程,调度器会新建线程,并将其绑定到该逻辑处理器上;
调度器会从本地运行队列中选择另外的goroutine来运行;
一旦被阻塞的系统调用执行完成并返回,对应的goroutine会放回到本地运行队列,之前的线程会保存好以遍之后使用
go语言实战读书笔记之 goroutine

如果一个goroutine需要做一个网络I/O调用:
goroutine会和逻辑处理器分离,并移到集成了网络轮询器的运行时;
一旦该轮询器指示某个网络读或者写操作已经就绪,对应的gorouotine会重新分配搭配到逻辑处理器上来完成操作.

调度器对可以运行的逻辑处理器没有限制
语言运行时默认限制每个程序最多创建10000个线程,此限制可以通过调用runtime/debug包中的SetMaxThread方法来更改,如果程序试图使用更多的线程就会崩溃

创建两个goroutine,以并发的形式分别显示大写和小写的英文字母

func main(){
    runtime.GOMAXPROCS(1) //分配一个逻辑处理器给调度器使用
    var wg sync.WaitGroup
    wg.Add(2).  //计数器加2,表示要等待两个goroutine
    fmt.println("Start Goroutine")
    go func(){
        defer wg.Done()
        for i:=0;i<3;i++{
          for char:='a';char<'a'+26;char++{
           fmt.printf("%c",char)
           }
        }
    }()
       go func(){
        defer wg.Done() //通知main函数工作已完成
        for i:=0;i<3;i++{
          for char:='A';char<'A'+26;char++{
           fmt.printf("%c",char)
           }
        }
    }()
   fmt.println("Waiting To Finish")
   wg.wait()
}

WaitGroup:是一个计数信号量,可以用来记录并维护运行的goroutine.
如果waitgroup大于0,wait方法就会阻塞

defer:会修改函数调用时机,在正在执行的函数返回时才真正调用defer声明的函数

只有在有多个逻辑处理器,且可以同时让每个goroutine运行在一个可用的物理处理器上时,goroutine才会并行运行.

相关标签: golang