go实例之轻量级线程goroutine、通道channel与select

1、goroutine线程

  goroutine是一个轻量级的执行线程。假设有一个函数调用f(s),要在goroutine中调用此函数,请使用go f(s)。 这个新的goroutine将与调用同时执行。

  示例代码如下:

 1 package main
 2 
 3 import "fmt"
 4 
 5 func f(from string) {
 6     for i := 0; i < 3; i++ {
 7         fmt.Println(from, ":", i)
 8     }
 9 }
10 
11 func main() {
12 
13     // Suppose we have a function call `f(s)`. Here's how
14     // we'd call that in the usual way, running it
15     // synchronously.
16     f("direct")
17 
18     // To invoke this function in a goroutine, use
19     // `go f(s)`. This new goroutine will execute
20     // concurrently with the calling one.
21     go f("goroutine")
22 
23     // You can also start a goroutine for an anonymous
24     // function call.
25     go func(msg string) {
26         fmt.Println(msg)
27     }("going")
28 
29     // Our two function calls are running asynchronously in
30     // separate goroutines now, so execution falls through
31     // to here. This `Scanln` code requires we press a key
32     // before the program exits.
33     var input string
34     fmt.Scanln(&input)
35     fmt.Println("done")
36 }

  执行上面代码,将得到以下输出结果

1 direct : 0
2 direct : 1
3 direct : 2
4 goroutine : 0
5 goroutine : 1
6 goroutine : 2
7 going

2、通道

  通道是连接并发goroutine的管道。可以从一个goroutine向通道发送值,并在另一个goroutine中接收到这些值。

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 
 7     // Create a new channel with `make(chan val-type)`.
 8     // Channels are typed by the values they convey.
 9     messages := make(chan string)
10 
11     // _Send_ a value into a channel using the `channel <-`
12     // syntax. Here we send `"ping"`  to the `messages`
13     // channel we made above, from a new goroutine.
14     go func() { messages <- "ping" }()//使用"<-"向通道发送消息
15 
16     // The `<-channel` syntax _receives_ a value from the
17     // channel. Here we'll receive the `"ping"` message
18     // we sent above and print it out.
19     msg := <-messages//"从通道读取数据"
20     fmt.Println(msg)
21 }

   默认情况下,通道是未缓冲的,意味着如果有相应的接收(<- chan)准备好接收发送的值,它们将只接受发送(chan <- )。使用make的第二个参数指定缓冲大小

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6 
 7     // Here we `make` a channel of strings buffering up to
 8     // 2 values.
 9     messages := make(chan string, 2)
10 
11     // Because this channel is buffered, we can send these
12     // values into the channel without a corresponding
13     // concurrent receive.
14     messages <- "buffered"
15     messages <- "channel"
16 
17     // Later we can receive these two values as usual.
18     fmt.Println(<-messages)
19     fmt.Println(<-messages)
20 }

3、通道同步

 1 package main
 2 
 3 import "fmt"
 4 import "time"
 5 
 6 // This is the function we'll run in a goroutine. The
 7 // `done` channel will be used to notify another
 8 // goroutine that this function's work is done.
 9 func worker(done chan bool) {
10     fmt.Print("working...")
11     time.Sleep(time.Second)
12     fmt.Println("done")
13 
14     // Send a value to notify that we're done.
15     done <- true
16 }
17 
18 func main() {
19 
20     // Start a worker goroutine, giving it the channel to
21     // notify on.
22     done := make(chan bool, 1)
23     go worker(done)
24 
25     // Block until we receive a notification from the
26     // worker on the channel.
27     <-done
28 }

  当使用通道作为函数参数时,可以指定通道是否仅用于发送或接收值。这种特殊性增加了程序的类型安全性。chan<-表示发送,<-chan表示接收

4、select

  每个通道将在一段时间后开始接收值,以模拟阻塞在并发goroutines中执行的RPC操作。我们将使用select同时等待这两个值,在每个值到达时打印它们。

 1 package main
 2 
 3 import "time"
 4 import "fmt"
 5 
 6 func main() {
 7 
 8     // For our example we'll select across two channels.
 9     c1 := make(chan string)
10     c2 := make(chan string)
11 
12     // Each channel will receive a value after some amount
13     // of time, to simulate e.g. blocking RPC operations
14     // executing in concurrent goroutines.
15     go func() {
16         time.Sleep(time.Second * 1)
17         c1 <- "one"
18     }()
19     go func() {
20         time.Sleep(time.Second * 2)
21         c2 <- "two"
22     }()
23 
24     // We'll use `select` to await both of these values
25     // simultaneously, printing each one as it arrives.
26     for i := 0; i < 2; i++ {
27         select {
28         case msg1 := <-c1:
29             fmt.Println("received", msg1)
30         case msg2 := <-c2:
31             fmt.Println("received", msg2)
32         }
33     }
34 }

5、相关文章

  Go超时(timeouts)实例

  Go非阻塞通道操作实例:使用selectdefault子句来实现非阻塞发送,接收

  Go关闭通道实例:close直接关闭通道

  Go通道范围实例:通道关闭了,还可以接收通道中的数据

 

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!! 

 

  


很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。 


 

  


很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考