golang-协程 Coroutine

爱吃豆包 · · 559 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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

抢占式:是有操作系统主动切换线程执行
非抢占式:是由我协程主动交出控制权

编译器/解释器/虚拟机层面的多任务
多个协程可能在一个或多个线程上运行!

检测数据冲突

go run -race xxxxx.go

goroutne 之间可以用 channel 管道进行交流沟通!

goroutine的定义

任何函数只需要加上 go 就能送给调度器运行
不需要再定义时区分是否是异步函数
调度器在合适的点进行切换(这个点不好把控)

goroutine 可能的切换点

在 I/O, SELECT
channel
等待锁
函数调用时(有时)
runtime.Gosched()

go 协程例子

package main

import (
    "fmt"
    "time"
)

func main() {

    for i := 0; i< 10; i++ {
        go func(j int) {
            for  {
                // 这里是 fmt.Printf 打印,是一个IO的操作,涉及到IO操作是要进行切换的!
                fmt.Printf("开始打印!%d\n", j)
            }

        }(i)
    }

    // 睡眠一段时间
    time.Sleep(time.Millisecond)
    
}

func printArr(){
    var a [10]int
    for i := 0; i< 10; i++ {
        go func(j int) {
            for  {
                // 这个时候其他的协程是无法进行执行的
                // 因为我这个进来的协程,没有办法交出控制权
                // 比如我可以执行完某个打印操作,我就把控制权交出去
                // 但是在这里是一个死循环,所有没有结束的地方,所有无法交出控制权
                a[i]++

                // 手动交出控制权
                // runtime.Gosched()
            }

        }(i)
    }

    // 睡眠一段时间
    time.Sleep(time.Millisecond)
    fmt.Println(a)
}


func printArrTest(){
    var a [10]int
    for i := 0; i< 10; i++ {
        // 这里没有像上面那样通过这里传入数据
        // 就表示这个 func 是使用上面循环的 i 参数,这样就形成了一个闭包
        // 当 i = 10的时候,已经进不去循环了,但是我里面使用的还是 for 循环的 i,
        // 所以我里面闭包使用的 i 始终是同一个 i,当 i = 10 的时候,我里面正好 a 数组没有下坐标为 10的位置,所以就报错
        go func() { // 所以推荐通过,这里传入参数,就像上面的那个例子一样
            for  {
                // 这个时候其他的协程是无法进行执行的
                // 因为我这个进来的协程,没有办法交出控制权
                // 比如我可以执行完某个打印操作,我就把控制权交出去
                // 但是在这里是一个死循环,所有没有结束的地方,所有无法交出控制权
                a[i]++

                // 手动交出控制权
                // runtime.Gosched()
            }

        }()
    }

    // 睡眠一段时间
    time.Sleep(time.Millisecond)
    fmt.Println(a)
}



有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:爱吃豆包

查看原文:golang-协程 Coroutine

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

559 次点击  
加入收藏 微博
上一篇:golang-channel
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传