
g0 协程属于调度器启动协程如下所示 对应线程属于 循环调用方式 不断的调用属于go 协程的业务方法 对应的版本是 go 0.X 版本内


多线程 抢占的时候 需要进行枷锁的方式 适用于 Go 1.0 版本
操作系统线程执行一个调度的循环,顺序指向Goroutine, 调度循环非常像线程池,如果协程顺序执行,无法并发
问题: 1. 协程顺序执行 无法并发
问题: 2. 多线程并发时候,会导致协程队列的全局锁问题
所以 出现 G-M-P 调度方式
解决问题:多线程并发的时候,会抢占协程队列全局锁
在本地队列, 每个线程获取全局锁时候获取多个协程任务, 只有一个线程进行访问 不存在锁问题


P的作用:
go 语言中新创建协程会立即执行 ,只有P本地队列满时候,放入到全局队列中, 新创建协程属于 newproc函数解决问题:协程顺序执行,无法并发 在go 语言中 支持进行挂起,执行其他的新协程任务,每次线程循环61次后从全局获取任务。
runtime.morestack线程可以注册对应的信号的处理函数, 注册SIGURG 信号 处理函数
2. GC工作时候,向目标线程发送信号
too many socket 连接出问题不建议使用,Go语言线程 已经相当于池化,不要在二级池化,go 语言初衷 希望协程即用即销毁,不要池化)// 预先创建一定数量协程, 将任务创建送入到等待的队列
不推荐使用
牺牲并发的性能func do (i int , ch chan struct{}){
fmt.Println(i)
time.Sleep(time.Second)
<- ch
}
// 利用 channel的缓冲区,控制协程产生的数量,一旦缓冲区被阻塞了, 不会产生更多的协程
// 适合场景 大量批量的设置协程
接收必须要发送前不然,导致缓冲区阻塞针对 无缓冲区的 管道,必须要先从管道里面获取接受数据,才能进行数据塞入,所以对于无
缓冲区的管道 使用 协程接收在发送的前面 不然导致阻塞
协程进行socket 通信的监听避免协程竞争和数据冲的问题更高级的抽象,降低开发难度,增加程序的可读性模块间更容易解耦,增加扩展性和维护性Ring buffer 环形缓冲区, 大幅度降低GC的开销

有等待的协程G,从G接收
接收数据前,已经有G在休眠中等待发送,并且channel 无缓存

有等待的G,从缓存接收
数据在接收前已经有G在休眠等待发送,并且这个Channel有缓存

接收缓存
接收G没有在休眠并且channel有数据

阻塞接收
没有G在休眠等待,并且缓存也没有数据,说白了 就是没有数据进来

总结
对于写非阻塞的channel 使用select 非阻塞的形式使用select