您的位置:首页 > 编程语言 > Go语言

Go语言自学笔记

2016-10-06 11:03 393 查看
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个,而读的线程只有一个(主线程)。写的速度比读的快。当是无缓存时,情况是读完一个写一个。有缓存时,不必等读,直接可以写入缓存,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  go语言