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以后默认开启多核