golang学习3-线程协程理解

40次阅读

共计 1346 个字符,预计需要花费 4 分钟才能阅读完成。

  1. 进程、线程、协程区别

=============

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!

*/

正文完
 0