golang:channel

来源:互联网 发布:网络研修提问 编辑:程序博客网 时间:2024/05/05 22:49
                                                                                                     

先来看看上一篇文章我们提到去掉runtime.Gosched()程序会变成什么样子。代码如下:

package main  import (     "fmt"     //"runtime" )  func say(s string) {     for i := 0; i < 5; i++ {         //释放时间片         //runtime.Gosched()         fmt.Println(s)     } } func main() {     go say("world") //开一个新的Goroutines执行     say("hello")    //当前Goroutines执行 }

运行结果如下:

$ go run test.go hello hello hello hello hello

在上面的例子中,我们看到,world这个单词并没有被打印出来。是不是感觉很奇怪?明明开了goroutine,却没有执行。实际上,在运行的时候被go修饰的函数,会进入主线程以外的线程等待执行,但因为主线程后面没有动作需要执行了,main函数结束就退出了,而goroutine队列的程序还没来得及执行就被注销了。这个时候如果我们在最后加上time.Sleep(time.Second)就可以看到world被输出了。
结果如下:

$ go run test.go hello hello hello hello hello world world world world world

看到这个你也许又冒出来要给疑问,为啥不是交替输出的?其实这是因为我们的机器太快了,还没等到下个调度,就已经执行完了。这个调度是go自动分配的,但我们可以通过上篇文章的runtime.Gosched()来手动释放,如果你把上面的i改成一个大点的数字,比如100000,这个时候你就能看到交替输出。

好了,现在来看今天的内容吧——go channel(通道)。Go语言提倡“以通信作为手段来共享内存”。因此在Go routine中go语言提供了channel这个方式来共享内存。看下面的示意图。各个线程之间通过channel来共享内存。golang:channel
现在对channel有了一个基本的概念,那它到底怎么用呢?看一个简单的示例:

package main  import (     "fmt" )  func main() {     //定义一个通道messages     messages := make(chan string)      //开线程,向messages发送字符串     go func() { messages <- "ping" }()      //主线程中读取messages     msg := <-messages     fmt.Println(msg) }

默认情况通道的读取是阻塞的,所以这里并没有看到Sleep函数或者Gosched函数。
输出结果如下

$ go run test.go ping

channel遵循FIFO原则,已接受的元素会立即销毁。
今天的文章到这里就结束了,下一期我们接着讲channel。感谢各位的品鉴,关注公众号(cainiaopark)更多精彩内容等你来批阅。

版权申明:练习代码出https://gobyexample.com。其他为本人翻译或者创作,不代表源文作者和网站的观点。扫描二维码获取更多编程和科普小知识。

golang:channel

某人说天天发美女不发她,这是几个意思,所以今天。。。

golang:channel



查看原文:http://www.zoues.com/2016/10/20/golangchannel/
0 0
原创粉丝点击