前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go基础——Goroutine

Go基础——Goroutine

作者头像
羊羽shine
发布2019-05-29 22:31:59
5460
发布2019-05-29 22:31:59
举报
文章被收录于专栏:Golang开发Golang开发
Thread 和Groutine

创建时默认的stackd的大小 JDK5以后Java Thread stack默认的是1M Groutine 的stack初始化为2K KSE(kernel space entity)的对应关系 Java Thread是1:1 Groutine 的是M:N

Groutine

轻量级线程 非抢占式多任务处理,由协程主动交出控制权。

代码语言:javascript
复制
func TestGroutine(t *testing.T) {
    for i := 0; i < 10; i++ {
        go func(i int) {
            t.Log(i)
        }(i)
    }
}

编译器/解释器/虚拟机层面的多任务

Goroutine调度模型

基本概念 M(machine) M代表着真正的执行计算资源,可以认为它就是os thread(系统线程)。 M是真正调度系统的执行者,每个M就像一个勤劳的工作者,总是从各种队列中找到可运行的G,而且这样M的可以同时存在多个。 M在绑定有效的P后,进入调度循环,而且M并不保留G状态,这是G可以跨M调度的基础。 P(processor) P表示逻辑processor,是线程M的执行的上下文。 P的最大作用是其拥有的各种G对象队列、链表、cache和状态。 G(goroutine) 调度系统的最基本单位goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等。 在G的眼中只有P,P就是运行G的“CPU”。相当于两级线程

goroutine可能的切换点

I/O,slect channel 等待锁 函数调用 runtime.Gosched()

资源竞争检测

go build -race

代码语言:javascript
复制
import (
    "fmt"
    "sync"
)

var(
    wg sync.WaitGroup
    globalVal int
)
func count(){
    defer wg.Done()
    for i:=0;i<10000;i++{
        globalVal++
    }
}

func main() {
    wg.Add(2)
    go count()
    go count()
    wg.Wait()
    fmt.Println(globalVal)
}

执行 go run --race main.go 会告诉你有数据竞争DATA RACE的问题

代码语言:javascript
复制
 go run  --race main.go
==================
WARNING: DATA RACE
Read at 0x000001211840 by goroutine 7:
  main.count()
      /Users/baxiang/go/src/GoBase/main.go:15 +0x6f

Previous write at 0x000001211840 by goroutine 6:
  main.count()
      /Users/baxiang/go/src/GoBase/main.go:15 +0x8b

Goroutine 7 (running) created at:
  main.main()
      /Users/baxiang/go/src/GoBase/main.go:22 +0x77

Goroutine 6 (running) created at:
  main.main()
      /Users/baxiang/go/src/GoBase/main.go:21 +0x5f
==================
179762
Found 1 data race(s)
exit status 66
sync.Mutex
代码语言:javascript
复制
func TestTraceData(t *testing.T) {
    sum := 0
    var mut sync.Mutex
    for i := 0; i < 10000; i++ {
        go func(i int) {
            mut.Lock()
            sum++
            mut.Unlock()
        }(i)
    }
    time.Sleep(time.Second * 2)
    t.Log(sum)
}
WaitGroup
代码语言:javascript
复制
func TestTraceData(t *testing.T) {
    sum := 0
    var wg sync.WaitGroup
    var locker sync.Mutex
    for i := 0; i < 10000; i++ {
        wg.Add(1)
        go func() {
            locker.Lock()
            sum++
            locker.Unlock()
            wg.Done()
        }()
    }
    wg.Wait()
    t.Log(sum)
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Thread 和Groutine
  • Groutine
  • Goroutine调度模型
  • goroutine可能的切换点
  • 资源竞争检测
  • sync.Mutex
  • WaitGroup
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档