Go中的chan

go中的chan是动态的,因此千万不要把chan想象成slice切片类型的数据。

  • 只要chan不close可以永远发送数据和接受数据
  • 如果channel里面没有数据,接收方会阻塞
  • 如果没有人正在等待channel的数据,发送方会阻塞
  • 从一个close的channel取数据永远不会阻塞, 同时获取的数据为默认值(与定义的chan类型一致)

下面这段代码,会解释上面这四个chan特点:

package main

import (
    "net/http"
    "fmt"
    "sync"
)

func printUrl(url string) {
    res, err := http.Get(url)
    if err != nil{
        fmt.Println(err)
        return
    }
    defer res.Body.Close()
    fmt.Println(url, res.Status)


}

func work2(urls chan string, wg *sync.WaitGroup)  {
    for{
        url, ok := <- urls      // 判断取出的数据是否为false 说明chan关闭
        if !ok{
            break
        }
        printUrl(url)
    }
    wg.Done()

}
func work(urls chan string, wg *sync.WaitGroup) {

    for i := range urls{        // chan中有一条数据会循环一次知道chan关闭
        printUrl(i)
    }
    wg.Done()

}

func main() {
    url := "http://www.baidu.com"
    var u []string

    for i :=0; i<15;i ++{   // 先生成一些数据
        u = append(u, url)
    }
    wg := new(sync.WaitGroup)   // 利用WaitGroup的方式协程同步
    //wg.Add(5)                 // 可一次性添加任务总数
    urlchann := make(chan string)

    for i:=0; i<5 ;i++  {
        wg.Add(1)           // 也可每创建一个任务 添加一个标识
        go work(urlchann, wg)
    }

    for _, line := range u{
        urlchann <- line        // 将任务需要的数据添加到队列中
    }
    close(urlchann)         // 关闭chan
    wg.Wait()
}

代码中的Work与Work2效果是一样的。

特别要记住一点,chan的大小是动态的,不要理解为像slice那样的固定长度。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 出处---Go编程语言 欢迎来到 Go 编程语言指南。本指南涵盖了该语言的大部分重要特性 Go 语言的交互式简介,...
    Tuberose阅读 18,522评论 1 46
  • 第一章五个程序 都很好!但是初学编程/没有其他语言基础的不容易看懂。 记一遍不熟悉的东西: who = strin...
    暗黑破坏球嘿哈阅读 1,459评论 0 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,026评论 19 139
  • Go语言做Web编程非常方便,并且在开发效率和程序运行效率方面都非常优秀。相比于Java,其最大的优势就是简便易用...
    暗黑破坏球嘿哈阅读 9,075评论 6 66
  • 订阅了这个专栏以后,我有什么变化? 【做好一件事情】最开始订阅专栏的时候,老师曾说,坚持每天打开专栏,每天留言,就...
    花生米不高兴阅读 172评论 0 0