标签:分享 空闲 sleep img 文件 资源分配 完成 下载 利用
一:gorouting的必要性
假如设计一个程序1-10000000000000数字之间那些是偶数
①:传统思路上设计一个循环,在循环中判断
②:使用并发或者并行的方法,将判断那些书偶数的任务分配给多个grouting去完成,这样将大大提高速率。
二:进程与线程
①:进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位;
②:线程是进程的一个执行实例,是程序执行的最小单位,他是比进程更小的能独立运行的基本单位;
③:一个进程可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行;
④:一个程序至少有一个进程,一个进程至少有一个线程;
⑤:举例说明,在电脑上启动百度云客户端就是启动一个百度云进程,当利用百度云客户端下载一个文件时,就会创建一个下载线程,当下载10个文件时就会创建10个下载线程。
三:并发和并行
①:多线程程序在单核cpu上运行就是并发;
②:多线程程序在多核cpu上运行就是并行;
③:示意图
四:Go协程和Go主线程
Go主线程(也可以理解为进程),一个Go线程可以有多个协程。
①:Go协程的特点:有独立的栈空间、共享程序堆空间、调度由用户控制、协程是轻量级的线程
②:原理示意图
五:gorouting使用举例
①:
package main import ( "fmt" "strconv" "time" ) func gr() { for i := 1; i <= 3; i++{ fmt.Println("hello gr"+strconv.Itoa(i)) time.Sleep(time.Nanosecond) } } func main() { go gr() for i := 1; i <= 3; i++{ fmt.Println("hello main"+strconv.Itoa(i)) time.Sleep(time.Nanosecond) } } 结果 [ `go run gorouting.go` | done ] hello main1 hello gr1 hello gr2 hello main2 hello main3 hello gr3
由有代码可知main主线程和gr()协程同时执行
②:主线程与协程原理图
③:总结
主线程是一个物理线程,直接作用在cpu上,是重量级的,非常耗费资源;
协程从主线程开启,是轻量级的线程,是逻辑态。资源耗费较小;
golang的协程机制是重要特点,可以轻松的开启上万个协程,其他语言并发机制一般是基于线程的,开启过多线程会导致资源耗费大。
六:gorouting的MPG的调度模式
①:基本介绍
M:操作系统的主线程(物理线程)
P:协程执行树妖的条件(如是否有足够的cpu资源等等)
G:协程
②:MPG的第一种运行状态
当前有三个M,如果三个M在同一个cpu运行,就是并发,如果在不同cpu运行就是并行;
M1,M2,M3正在执行一个协程G,M1的协程队列有三个协程等待调用执行,M2同M2,M3有两个
由上图可知Go协程是轻量级的线程,是逻辑态,Go可以轻松起上上万协程
其他编程c/java的多线程,往往是内核的,比较重量级,几千个就可能耗光cpu资源
③:MPG的第二种运行状态
M0主线程正在执行G哦协程,另外三个协程在队列等待被执行;
如果G0即正在执行的协程阻塞,如读出数据库等;
这时就会创建M1主线程(也可能是从已有的线程池中取出M1),并且将在等待的3个协程挂到M1上并开始执行,M0的主线程任然执行G0;
这样的MPG调度模式既可以让G0继续执行,又不会让队列的其他协程一直被阻塞,任然可以并发或并行执行;
等到G0执行完毕,M0会被放到空闲的主线程或继续执行其他协程
七:设置Go的运行cpu数
①:go1.8后,默认程序运行在多个核上。
②:go1.8前,默认只运行在一个核,需要设置才可以更高效的利用cpu
package main import ( "fmt" "runtime" ) func main() { //获取当前系统cpu的数量 num := runtime.NumCPU() //设置go运行程序的核实 runtime.GOMAXPROCS(num) fmt.Println("cpu核数:",num) } 结果 [ `go run gorouting.go` | done ] cpu核数: 4
标签:分享 空闲 sleep img 文件 资源分配 完成 下载 利用
原文地址:https://www.cnblogs.com/louis181214/p/10321773.html