温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Go语言通道之缓冲通道实例分析

发布时间:2022-07-16 13:48:17 来源:亿速云 阅读:135 作者:iii 栏目:开发技术

这篇“Go语言通道之缓冲通道实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言通道之缓冲通道实例分析”文章吧。

有缓冲的通道相比于无缓冲通道,多了一个缓存的功能,如下图描述的一样:

Go语言通道之缓冲通道实例分析

从图上可以明显看到和无缓冲通道的区别,无缓冲必须两个Goroutine都进入通道才能进行数据的交换,这个不用,如果数据有,直接就能拿走。

package ChannelDemo

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

const (
    numberGoroutines = 4
    taskLoad         = 10
)

var bufferWg sync.WaitGroup

func init() {
    rand.Seed(time.Now().Unix())
}

func main() {
    //创建了一个10任务的缓冲通道
    tasks := make(chan string, taskLoad)
    bufferWg.Add(numberGoroutines)

    //创建4个Goroutine
    for gr := 1; gr <= numberGoroutines; gr++ {
        go worker(tasks, gr)
    }

    //向缓冲通道中放入数据
    for post := 1; post <= taskLoad; post++ {
        tasks <- fmt.Sprintf("Task : %d", post)
    }

    close(tasks)

    bufferWg.Wait()
}

func worker(tasks chan string, worker int) {
    defer bufferWg.Done()

    for {
        task, ok := <-tasks
        if !ok {
            fmt.Printf("Worker: %d : 结束工作 \n", worker)
            return
        }

        fmt.Printf("Worker: %d : 开始工作 %s\n", worker, task)

        //随机处理一下工作的时间
        sleep := rand.Int63n(100)
        time.Sleep(time.Duration(sleep) * time.Millisecond)

        fmt.Printf("Worker: %d : 完成工作 %s\n", worker, task)
    }
}

运行结果:

Worker: 3 : 开始工作 Task : 4
Worker: 2 : 开始工作 Task : 2
Worker: 1 : 开始工作 Task : 1
Worker: 4 : 开始工作 Task : 3
Worker: 4 : 完成工作 Task : 3
Worker: 4 : 开始工作 Task : 5
Worker: 2 : 完成工作 Task : 2
Worker: 2 : 开始工作 Task : 6
Worker: 3 : 完成工作 Task : 4
Worker: 3 : 开始工作 Task : 7
Worker: 1 : 完成工作 Task : 1
Worker: 1 : 开始工作 Task : 8
Worker: 3 : 完成工作 Task : 7
Worker: 3 : 开始工作 Task : 9
Worker: 1 : 完成工作 Task : 8
Worker: 1 : 开始工作 Task : 10
Worker: 4 : 完成工作 Task : 5
Worker: 4 : 结束工作
Worker: 3 : 完成工作 Task : 9
Worker: 3 : 结束工作
Worker: 2 : 完成工作 Task : 6
Worker: 2 : 结束工作
Worker: 1 : 完成工作 Task : 10
Worker: 1 : 结束工作 

因为哪一个worker先从通道中取值有系统自己进行调度的,所以每次运行的结果稍微不同,但是相同的是10个任务被4个协程有条不紊的完成了

注意:main中有一句代码 Close(tasks) 关闭通道的代码非常重要。当通道关闭后,goroutine 依旧可以从通道接收数据,但是不能再向通道里发送数据。

能够从已经关闭的通道接收数据这一点非常重要,因为这允许通道关闭后依旧能取出其中缓冲的全部值,而不会有数据丢失.

以上就是关于“Go语言通道之缓冲通道实例分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI