(golang学习)3. 线程、协程理解
2012 年 3 月 9 日
- 进程、线程、协程区别
=============
a.各自特点
参考《 详细介绍 进程、线程和协程的区别
》
- 进程:拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度;
- 线程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,标准线程由操作系统调度;
- 协程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
协程与线程:
每个单位时间内,一个CPU只能处理一个线程(操作系统:thread),线程是CPU处理的单位或单元,底层资源占用中等(比进程少)。线程中程序的执行过程是:同步阻塞的(依次执行),非抢占式的(依代码编写顺序)。开发上比较清晰明了。
协程是“用户级”的线程,通过把线程的分段运行:主动暂停、主动运行,切换逻辑点,针对i/o请求可以节约连接、对方处理的中间环节等待时间,一个线程上可以跑多个协程。协程中的程序执行是触发、跳转的,异步非阻塞的(事件触发),抢占式的(线程挂起等待响应)。开发上很复杂。
b.上代码
go协程
package main import ( "fmt" "math/rand" "strconv" "time" ) type array2j struct { a []string b string } func main() { ch := make(chan string, 3) c2 := make(chan string) var queue array2j for i:=1; i<=5; i++ { go func(i int) { fmt.Println("go func:" + strconv.Itoa(i)) ch <- strconv.Itoa(i) + "_ch_" + strconv.Itoa(rand.Int()) }(i) } for j:=1; j<=2; j++ { go func() { time.Sleep(1 * time.Second) ch <- "c2" }() } time.Sleep(1 * time.Second) for { select { case a,e := <-ch: fmt.Println(a,e) queue.a = append(queue.a, a) case b,e := <-c2: fmt.Println(b,e) queue.b = b } if len(ch) + len(c2) == 0 { fmt.Println("queue", queue) break } res, err := <- ch fmt.Println(res, err) } fmt.Println("hello go!") } /** go func:1 go func:4 go func:2 go func:3 go func:5 1_ch_5577006791947779410 true 4_ch_8674665223082153551 true 2_ch_6129484611666145821 true 3_ch_4037200794235010051 true 5_ch_3916589616287113937 true c2 true c2 true queue {[1_ch_5577006791947779410 4_ch_8674665223082153551 2_ch_6129484611666145821 3_ch_4037200794235010051 5_ch_3916589616287113937 c2 c2] } hello go! */