Golang中的channel代码示例----无缓冲、有缓冲、range、close

栏目: Go · 发布时间: 7年前

// code_043_channel_unbuffered project main.go
package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan int, 0) //无缓冲的通道

    //内置函数 len 返回未被读取的缓冲元素数量, cap 返回缓冲区大小
    fmt.Printf("len(c)=%d, cap(c)=%d\n", len(c), cap(c))

    go func() {
        defer fmt.Println("子协程结束")

        for i := 0; i < 3; i++ {
            fmt.Printf("子协程正在运行[%d]: len(c)=%d, cap(c)=%d\n", i, len(c), cap(c))
            c <- i //备注:如果在上面的话, 不会执行最后一次Printf
        }
    }()

    time.Sleep(2 * time.Second) //延时2s

    for i := 0; i < 3; i++ {
        num := <-c //从c中接收数据,并赋值给num
        fmt.Println("num = ", num)
    }

    fmt.Println("main协程结束")
}
// code_044_channel_buffered project main.go
package main

import (
    "fmt"
    "time"
)

//有缓冲的通道(buffered channel)是一种在被接收前能存储一个或者多个值的通道。
//只有在通道中没有要接收的值时,接收动作才会阻塞。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。

//有缓冲的通道和无缓冲的通道之间的不同:
//1)无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换;
//2)有缓冲的通道没有这种保证
func main() {
    c := make(chan int, 3)
    fmt.Printf("len(c)=%d, cap(c)=%d\n", len(c), cap(c))
    go func() {
        defer fmt.Println("子协程结束")
        for i := 0; i < 3; i++ {
            c <- i
            fmt.Printf("子协程正在运行[%d]: len(c)=%d, cap(c)=%d\n", i, len(c), cap(c))
        }
    }()

    time.Sleep(2 * time.Second)
    for i := 0; i < 3; i++ {
        num := <-c
        fmt.Println("num=", num)
    }
    fmt.Println("main协程结束")

}
// code_045_channel_range_close project main.go
package main

import (
    "fmt"
)

//注意点:
//channel不像文件一样需要经常去关闭,只有当你确实没有任何发送数据了,或者你想显式的结束range循环之类的,才去关闭channel;
//关闭channel后,无法向channel 再发送数据(引发 panic 错误后导致接收立即返回零值);
//关闭channel后,可以继续向channel接收数据;
//  对于nil channel,无论收发都会被阻塞。

/* close()的使用
func main() {
    c := make(chan int)

    go func() {
        for i := 0; i < 5; i++ {
            c <- i
        }

        //把 close(c) 注释掉,程序会一直阻塞在 if data, ok := <-c; ok 那一行
        //注释后报错“死锁”:fatal error: all goroutines are asleep - deadlock!
        close(c)
    }()

    for {

        //ok为true说明channel没有关闭,为false说明管道已经关闭
        if data, ok := <-c; ok {
            fmt.Println(data)
        } else {
            break
        }
    }
    fmt.Println("Finished")
}

*/

func main() {
    c := make(chan int)

    go func() {
        for i := 0; i < 5; i++ {
            c <- i
        }
        close(c)
    }()

    for data := range c {
        fmt.Println(data)
    }
    fmt.Println("Finished")
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Rails 5敏捷开发

Rails 5敏捷开发

[美] Sam Ruby、[美] Dave Thomas、[美] David Heinemeier Hansson / 安道、叶炜、大疆Ruby技术团队 / 华中科技大学出版社 / 2017-12-30 / 115.00

本书以讲解“购书网站”案例为主线,逐步介绍Rails的内置功能。全书分为3部分,第一部分介绍Rails的安装、应用程序验证、Rails框架的体系结构,以及Ruby语言知识;第二部分用迭代方式构建应用程序,然后依据敏捷开发模式开展测试,最后用Capistrano完成部署;第三部分补充日常实用的开发知识。本书既有直观的示例,又有深入的分析,同时涵盖了Web开发各方面的知识,堪称一部内容全面而又深入浅出......一起来看看 《Rails 5敏捷开发》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具