Go语言自学笔记

wthfeng · · 1188 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)
    /*
        下面2行不能互换,主程序顺序执行,若先遇到 ch<-2,则在此阻塞了。程序不会向下执行
    */
    go f1(ch) //开启一个协程
    ch <- 2   //向channel中传送数据

}

func f1(ch chan int) {
    fmt.Println(<-ch) //输出数据

}

如果容量大于 0,通道就是异步的了:缓冲满载(发送)或变空(接收)之前通信不会阻塞,元素会按照发送的顺序被接收。如果容量是0或者未设置,通信仅在收发双方准备好的情况下才可以成功。
要在首要位置使用无缓冲通道来设计算法,只在不确定的情况下使用缓冲。

package main

import (
    "fmt"
)

func main() {
    const N int = 10
    data := []int{34, 23, 45, 23, 5, 2, 1, 456, 76, 46} //10个元素
    ch := make(chan int)
    for index, v := range data {
        go func(index, v int) {
            ch <- v
            fmt.Printf("index is %d,value is %d \n", index, v)

        }(index, v)
    }
    for i := 0; i < N; i++ {
        fmt.Println(<-ch)
    }

}

输出结果为

index is 0,value is 34
34
23
45
23
5
2
1
456
76
46

解释:
程序线性执行到第一个for循环时,for循环内的goroutine开始并发执行(即重开协程执行),10次循环结束后,开启了10个并发的协程(比线程更轻量的概念),而主程序相当于跑了10次空循环。

一方面,主线程执行下一个for循环,一方面那10个协程并发执行。
主线程当遇到第一个fmt.Println(<-ch) 时,查看channel中是否有值,若有值则读取并输出,无值则等待阻塞。
goroutine的协程执行内嵌函数,ch <- v 向channel中传值,若无线程接受则会阻塞。由于主线程的第二个for有接收值,当主线程接收完值后程序退出。由结果可见协程中的输出语句只打印了一条(0-n,随机),因为主程序接收完N个channel值就会退出,而打印语句在协程中处于传值后。
然后我们看下一个例子,只是在channel创建时指定了大小,channel就成了有缓存的channel。


package main

import (
    "fmt"
)

func main() {
    const N int = 10
    data := []int{34, 23, 45, 23, 5, 2, 1, 456, 76, 46}
    ch := make(chan int, N)
    for index, v := range data {
        go func(index, v int) {
            ch <- v
            fmt.Printf("index is %d,value is %d \n", index, v)

        }(index, v)
    }
    for i := 0; i < N; i++ {
        fmt.Println(<-ch)
    }

}

输出结果:

index is 0,value is 34
index is 1,value is 23
index is 2,value is 45
index is 3,value is 23
index is 4,value is 5
index is 5,value is 2
index is 6,value is 1
index is 7,value is 456
index is 8,value is 76
index is 9,value is 46
34
23
45
23
5
2
1
456
76
46

仅仅将channel变为有缓存结果就变了,因为写的线程有10个,而读的线程只有一个(主线程)。写的速度比读的快。当是无缓存时,情况是读完一个写一个。有缓存时,不必等读,直接可以写入缓存,


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:wthfeng

查看原文:Go语言自学笔记

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1188 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传