1. Go 中类线程基础概念
Goroutin概念:
Go语言中有个概念叫做goroutine, 这类似我们熟知的线程,但是更轻。
信道:
信道是什么?简单说,是goroutine之间互相通讯的东西。类似我们Unix上的管道(可以在进程间传递消息), 用来goroutine之间发消息和接收消息。其实,就是在做goroutine之间的内存共享
varchchanint=make(chanint,2)
2. 并行 、并发
并发:
Programming as the composition of independently executing processes. (Processes in the general sense, not Linux processes. Famously hard to define.)
将相互独立的执行过程综合到一起的编程技术。(这里是指通常意义上的执行过程,而不是Linux进程。很难定义。)
Concurrency is about dealing with lots of things at once.
并发是指同时处理很多事情。
Concurrency is about structure.
并发关乎结构。
Concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable.
并发提供了一种方式让我们能够设计一种方案将问题(非必须的)并行的解决。
Concurrency is a way to structure a program by breaking it into pieces that can be executed independently.
并发是一种将一个程序分解成小片段独立执行的程序设计方法。
并行:
Programming as the simultaneous execution of (possibly related) computations.
同时执行(通常是相关的)计算任务的编程技术。
Parallelism is about doing lots of things at once.
并行是指同时能完成很多事情。
Parallelism is about execution.
并行关乎执行。
·两个队列,一个Coffee机器,那是并发
·两个队列,两个Coffee机器,那是并行
默认地,go所有的goroutines只能在一个线程里跑 。
如果当前goroutine不发生阻塞,它是不会让出CPU给其他goroutine的, 所以上面的例子的输出会是一个一个goroutine进行的
3. 多核调用
runtime调度器是个很神奇的东西,但是我真是但愿它不存在,我希望显式调度能更为自然些,多核处理默认开启。
关于runtime包几个函数:
Gosched让出cpu
NumCPU返回当前系统的CPU核数量
GOMAXPROCS设置最大的可同时使用的CPU核数
Goexit退出当前goroutine(但是defer语句会照常执行)
4. 总结
单核模式:
在同一个原生线程里,如果当前goroutine不发生阻塞,它是不会让出CPU时间给其他同线程的goroutines的,这是Go运行时对goroutine的调度,我们也可以使用runtime包来手工调度。
本文开头的两个例子都是限制在单核CPU里执行的,所有的goroutines跑在一个线程里面,分析如下:
l对于代码例子一(loop函数的那个),每个goroutine没有发生堵塞(直到quit流入数据), 所以在quit之前每个goroutine不会主动让出CPU,也就发生了串行打印
l对于代码例子二(time的那个),每个goroutine在sleep被调用的时候会阻塞,让出CPU, 所以例子二并发执行
多核模式:
当一个goroutine发生阻塞,Go会自动地把与该goroutine处于同一系统线程的其他goroutines转移到另一个系统线程上去,以使这些goroutines不阻塞
5. Go 多线程2中模式
模式一 :申明一个channel,并发产生的业务放入channel中,启动一个或者多个goroutin读取channel中的数据并处理
模式二:每一个新的请求,都启动一个新的goroutine来处理,处理结束后关闭goroutine
比较:
对于一般业务,用两种模式都差不多。主要区别在于:
第一种模式请求不一定是实时响应的,如果处理的逻辑中有阻塞,当所有goroutine都被阻塞时,系统运行就出问题了。
第二种模式每个goroutine都是独立的,互不影响,而且实时响应。但是频繁的新建和销毁goroutine会有性能损耗,不过go语言中goroutine是很轻量级的,这并不会带来太大的问题
6. 线程池
7. 提示:
GO 1.5以后默认开启多核