十二、并发

本文介绍Go语言中的goroutine和Channels的使用方法,包括如何通过Channels进行数据传递与同步,以及如何利用select监听多个Channels。

goroutine 是一个普通的函数,go作为开头

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 
 8 func ready(w string, sec int) {
 9     time.Sleep(time.Duration(sec) * time.Second)
10     fmt.Println(w, "is ready!")
11 }
12 
13 func main() {
14     go ready("Tea", 2)
15     go ready("Coffee", 1)
16     fmt.Println("I'm waiting")
17     time.Sleep(5 * time.Second) //移除这行程序会立即停止,所以需要用到管道channels
18 }

结果:

I'm waiting
         //立刻出现

Coffee is ready!
  //1秒出现

Tea is ready!      //2秒出现

这一机制通过channels的形式使用,与sehll中的双向管道做类比:可以通过它发送或者接受值。

必须使用make创建channel

    ci := make(chan int) //用于发送和接受整数
    cs := make(chan string)
    cf := make(chan interface{})
    ci <- 1   //发送整数1到channel ci 
    <-ci      //从channel ci接收整数
    i := <-ci //从channel ci接收整数,并保存到i中 
 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 //定义c作为int型的channel
 8 var c chan int
 9 
10 func ready(w string, sec int) {
11     time.Sleep(time.Duration(sec) * time.Second)
12     fmt.Println(w, "is ready!")
13     c <- sec
14 }
15 
16 func main() {
17     //初始化c
18     c = make(chan int)
19     go ready("Tea", 2)
20     go ready("Coffee", 1)
21     fmt.Println("I'm waiting")
22     //<-c 等待直到从channel上接收一个值,收到的值被丢弃
23     fmt.Println(<-c)
24     //<-c 两个goroutines,接收两个值
25     fmt.Println(<-c)
26 }

結果:

I'm waiting


Coffee is ready!


1


Tea is ready!


2

select

不得不從channel中读取两次23和25行,如果不知道启动了多少个go怎么办

通过select可以监听channel上输入的数据

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 
 8 //定义c作为int型的channel
 9 var c chan int
10 
11 func ready(w string, sec int) {
12     time.Sleep(time.Duration(sec) * time.Second)
13     fmt.Println(w, "is ready!")
14     c <- sec
15 }
16 
17 func main() {
18     //初始化c
19     c = make(chan int)
20     go ready("Tea", 2)
21     go ready("Coffee", 1)
22     fmt.Println("I'm waiting")
23     i := 0
24 L:
25     for {
26         select {
27         case <-c:
28             i++
29             if i > 1 {
30                 break L
31             }
32         }
33     }
34     fmt.Println(i)
35 }

結果:

I'm waiting


Coffee is ready!


Tea is ready!


2

虽然goroutine是并发执行的,但是它们并不是并行运行,同一时刻只会有一个go执行,利用runtime.GOMAXPROCE(n)可以

设置go并行执行的数量

创建chan

 ch := make(chan type, value) 

value == 0 无缓冲,例如: val := <-ch 它会被阻塞,直到有数据接收,任何发送(ch <-5 )将会被阻塞,直到数据被读出

value > 0   缓冲value的元素

关闭chan

x, ok = <-ch  当ok为true时表示chan没被关闭,可以读取数据

 

 

转载于:https://www.cnblogs.com/liubiaoren/archive/2013/02/02/2890508.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值