• Go语言学习之Go协程(goroutine)


    介绍

    说到Go语言,很多没接触过它的人,对它的第一印象,一定是它从语言层面天生支持并发,非常方便,让开发者能快速写出高性能且易于理解的程序。

    在 Python (为Py为例,主要是我比较熟悉,其他主流编程语言也类似)中,并发编程的门槛并不低,你要学习多进程,多线程,还要掌握各种支持并发的库 asyncio,aiohttp 等,同时你还要清楚它们之间的区别及优缺点,懂得在不同的场景选择不同的并发模式。

    而 Golang 作为一门现代化的编程语言,它不需要你直面这些复杂的问题。在 Golang 里,你不需要学习如何创建进程池/线程池,也不需要知道什么情况下使用多线程,什么时候使用多进程。因为你没得选,也不需要选,它原生提供的 goroutine (也即协程)已经足够优秀,能够自动帮你处理好所有的事情,而你要做的只是执行它,就这么简单。

    一个 goroutine 本身就是一个函数,当你直接调用时,它就是一个普通函数,如果你在调用前加一个关键字 go ,那你就开启了一个 goroutine

    // 执行一个函数
    func()
    
    // 开启一个协程执行这个函数
    go func()

    1.协程的初步使用

    一个Go程序的入口通常是main,程序启动后,main函数最先运行,我们称之为main goroutine

    在main中或者其下调用的代码中才可以使用go + func()的方法来启动协程

    main的地位相当于主线程,当main函数执行完成后,这个线程也就终结了,其下运行着的所有协程也不管代码是不是还在跑,也得乖乖退出

    因此如下代码运行完,只会输出hello,world,而不会输出hello,go(因为协程的创建需要时间,当hello,world打印后,协程还没来得及创建并执行)

    import "fmt"
    
    func mytest() {
        fmt.Println("hello, go")
    }
    
    func main() {
        // 启动一个协程
        go mytest()
        fmt.Println("hello, world")
    }

    对于刚学习Go的协程的人来说,可以使用time.Sleep来是main阻塞,使其他协程能够有机会运行完全,但你要注意的是 这并不是推荐的方式

    当我在代码里加入一行time.Sleep输出就符合预期了

    import (
        "fmt"
        "time"
    )
    
    func mytest() {
        fmt.Println("hello, go")
    }
    
    func main() {
        go mytest()
        fmt.Println("hello, world")
        time.Sleep(time.Second)
    }

    输出如下

    hello, world
    hello, go

    2.多个协程的效果

    为了看到并发效果,这里举个最简单的例子

    import (
        "fmt"
        "time"
    )
    
    func mygo(name string) {
        for i := 0; i < 10; i++ {
            fmt.Printf("In goroutine %s
    ", name)
            // 为了避免第一个协程执行过快,观察不到并发的效果,加个休眠
            time.Sleep(10 * time.Millisecond) 
        }
    }
    
    func main() {
        go mygo("协程1号") // 第一个协程
        go mygo("协程2号") // 第二个协程
        time.Sleep(time.Second)
    }

    输出如下,可以观察到两个协程就如两个线程一样,并发执行

    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
    In goroutine 协程1号
    In goroutine 协程2号
  • 相关阅读:
    CSS-calc 兼容写法
    一行代码轻松搞定各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
    地图调起URI API(通过连接直接调用百度地图)
    获取字体图标(阿里图标网站)
    CSS-解决苹果点击高亮、安卓select灰色背景(select下拉框在IOS中背景变黑、出现阴影问题)
    移动端 input 输入框实现自带键盘“搜索“功能并修改X
    常用正则表达式—邮箱(Email)
    JS正则表达式验证是否为11位有效手机号码
    input,textarea在ios和Android上阴影和边框的处理方法(在移动端)
    three.map.control
  • 原文地址:https://www.cnblogs.com/chadiandianwenrou/p/13886067.html
Copyright © 2020-2023  润新知