zoukankan      html  css  js  c++  java
  • 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. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。 

  • 相关阅读:
    wpf 不规则窗体
    wpf treeview使用expanded事件出错的问题
    获取文件图标
    C#操作快捷方式总结
    mysql 更改存储引擎,更改自增列计数值,更改默认字符集
    zend framework集成smarty
    文本文件数据导入mysql注意事项
    MYSQL 外键
    uchome 日志发布函数blog_post()
    mysql order by null
  • 原文地址:https://www.cnblogs.com/swarmbees/p/6599507.html
Copyright © 2011-2022 走看看