zoukankan      html  css  js  c++  java
  • Golang 入门系列(六)理解Go中的协程(Goroutine)

    前面讲的都是一些Go 语言的基础知识,感兴趣的朋友可以先看看之前的文章。https://www.cnblogs.com/zhangweizhong/category/1275863.html

    今天就来讲讲go 里面的高级功能,也是go语言重要的特性:Go协程(Goroutine)。

    什么是Go协程

    Go协程(Goroutine)是与其他函数同时运行的函数。可以认为Go协程是轻量级的线程,由Go运行时来管理。

    在函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行。当被调用的函数返回时,这个goroutine也自动结束。听着感觉像C# 中的Task。

    需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。

    Go 协程(Goroutine)之间通过信道(channel)进行通信,简单的说就是多个协程之间通信的管道。信道可以防止多个协程访问共享内存时发生资源争抢的问题。

    如何使用

    package main
    
    import (  
        "fmt"
        "time"
    )
    
    func hello() {  
        fmt.Println("Hello world goroutine")
    }
    func main() {  
        go hello()
        time.Sleep(1 * time.Second)
        fmt.Println("main function")
    }

    Channel(管道)

    Channel(管道) 可以被认为是协程之间通信的管道。与水流从管道的一端流向另一端一样,数据可以从信道的一端发送并在另一端接收。

    1. 定义

    每个channel都有一个类型。此类型是允许信道传输的数据类型。channel是类型相关的,一个channel只能传递一种类型的值,这个类型需要在声明channel时指定。

     

    2. 声明

    a. 我们需要通过内置函数 make 来创建一个信道。

    下面的代码声明了一个信道:

    var ch chan int

    b. 与其他变量定义一样,快速声明也是定义信道的一种有效而简洁的方式:

    a := make(chan int) 

    c. 创建一个带缓冲的channel

    c := make(chan int, 1024)
    
    // 从带缓冲的channel中读数据
    for i:=range c {
      ...
    }

    3. 发送和接收数据

    通过信道发送和接收数据的语法如下:

    data := <- a   // 从channel a 读取数据 
    a <- data      // 将数据写入到 channel a 

    箭头的指向说明了数据是发送还是接收。

    完整例子

    下面就直接说说,Goroutine和channel 共同使用的完整例子:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func Producer(queue chan<- int) {
        for i := 0; i < 10; i++ {
            queue <- i //写入
            fmt.Println("create :", i)
        }
    }
    
    func Consumer(queue <-chan int) {
        for i := 0; i < 10; i++ {
            v := <-queue  // 读出
            fmt.Println("receive:", v)
        }
    }
    
    func main() {
        queue := make(chan int, 88)
        go Producer(queue)
        go Consumer(queue)
        time.Sleep(1 * time.Second)
    }

    最后

    以上,就简单的介绍了Go语言中的协程(Goroutine)和信道(channel)。这两个功能特性,是go语言中重要的特性。大家可以写写其他的例子,熟悉掌握。

  • 相关阅读:
    js中对new Date() 中转换字符串方法toLocaleString的使用
    安装sass时遇到Failed to build gem native extension
    访问mapper方法提示invalid bound statement (not found)原因总结
    A query was run and no Result Maps were found for the Mapped Statement
    VS常用快捷键
    查看python和NumPy版本和安装路径
    Mybatis报错: There is no getter for property named xxx
    Map集合中get不存在的key值
    MySQL中DATA类型数据和DATATIME类型数据的比较
    shell 数组操作
  • 原文地址:https://www.cnblogs.com/zhangweizhong/p/9560536.html
Copyright © 2011-2022 走看看