前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go channel 通信通道

go channel 通信通道

作者头像
李海彬
发布2018-03-19 15:43:18
7950
发布2018-03-19 15:43:18
举报

go中最重要的一种通信通道就是channel

1.给一个 nil channel 发送数据,造成永远阻塞

2.从一个 nil channel 接收数据,造成永远阻塞

3.给一个已经关闭的 channel 发送数据,引起 panic

4.从一个已经关闭的 channel 接收数据,立即返回一个零值

package main

import "fmt"

// 此channel没有设置缓存,将被阻塞,所以都是执行default

func main() {

messages := make(chan string)

signals := make(chan bool)



select {

case msg := <-messages:

fmt.Println("received message", msg)

default:

fmt.Println("no message received")

}



msg := "hi"

select {

case messages <- msg:

fmt.Println("sent message", msg)

default:

fmt.Println("no message sent")

}



select {

case msg := <-messages:

fmt.Println("received message", msg)

case sig := <-signals:

fmt.Println("received signal", sig)

default:

fmt.Println("no activity")

}

}



// 输出

// no message received

// no message sent

// no activity

复制代码

Closing Channels.
package main

import "fmt"

// 这个例子在执行workder的工作时使用jobs管道来监听

// 当jobs关闭了,表示worker执行完毕,开始退出goroutine

// goroutine的退出又使用done来监听

func main() {

jobs := make(chan int, 5)

done := make(chan bool)



go func() {

for {

j, more := <-jobs

if more {

fmt.Println("received job", j)

} else {

fmt.Println("received all jobs")

done <- true

return

}

}

}()

// 发送三个jobs worker执行

for j := 1; j <= 3; j++ {

jobs <- j

fmt.Println("sent job", j)

}

close(jobs)

fmt.Println("sent all jobs")

// worker被关闭

<-done

}



// 输出

// sent job 1

// received job 1

// sent job 2

// received job 2

// sent job 3

// received job 3

// sent all jobs

// received all jobs

复制代码

Range over Channels.
package main

import "fmt"

// 遍历channel 有两种方法:select和range

// select 在channel输入或输出才能走case

// range可以再channel 甚至close后都能遍历值

func main() {



queue := make(chan string, 2)

queue <- "one"

queue <- "two"

close(queue)



for elem := range queue {

fmt.Println(elem)

}

}

// 输出

// one

// two

package main

import "fmt"

// 此channel没有设置缓存,将被阻塞,所以都是执行default

func main() {

    messages := make(chan string)

    signals := make(chan bool)



    select {

    case msg := <-messages:

        fmt.Println("received message", msg)

    default:

        fmt.Println("no message received")

    }



    msg := "hi"

    select {

    case messages <- msg:

        fmt.Println("sent message", msg)

    default:

        fmt.Println("no message sent")

    }



    select {

    case msg := <-messages:

        fmt.Println("received message", msg)

    case sig := <-signals:

        fmt.Println("received signal", sig)

    default:

        fmt.Println("no activity")

    }

}



// 输出

// no message received

// no message sent

// no activity

复制代码 Closing Channels.

package main

import "fmt"

// 这个例子在执行workder的工作时使用jobs管道来监听

// 当jobs关闭了,表示worker执行完毕,开始退出goroutine

// goroutine的退出又使用done来监听

func main() {

    jobs := make(chan int, 5)

    done := make(chan bool)



    go func() {

        for {

            j, more := <-jobs

            if more {

                fmt.Println("received job", j)

            } else {

                fmt.Println("received all jobs")

                done <- true

                return

            }

        }

    }()

// 发送三个jobs worker执行

    for j := 1; j <= 3; j++ {

        jobs <- j

        fmt.Println("sent job", j)

    }

    close(jobs)

    fmt.Println("sent all jobs")

// worker被关闭

    <-done

}



// 输出

// sent job 1

// received job 1

// sent job 2

// received job 2

// sent job 3

// received job 3

// sent all jobs

// received all jobs

复制代码 Range over Channels.

package main

import "fmt"

// 遍历channel 有两种方法:select和range

// select 在channel输入或输出才能走case

// range可以再channel 甚至close后都能遍历值

func main() {



    queue := make(chan string, 2)

    queue <- "one"

    queue <- "two"

    close(queue)



    for elem := range queue {

        fmt.Println(elem)

    }

}

// 输出

// one

// two

复制代码 Timers

package main

import "time"

import "fmt"



// time.NewTimer 定时一次

// 说明time是阻塞输出

func main() {

    // 定时2s

    timer1 := time.NewTimer(time.Second * 2)

    // 阻塞输出

    <-timer1.C

    fmt.Println("Timer 1 expired")



    timer2 := time.NewTimer(time.Second)

    go func() {

        <-timer2.C

        fmt.Println("Timer 2 expired")

    }()

    stop2 := timer2.Stop()

    if stop2 {

        fmt.Println("Timer 2 stopped")

    }

}



// 输出

// Timer 1 expired

// Timer 2 stopped
复制代码
Tickers
package main

import "time"

import "fmt"

// ticker 定时循环

func main() {



    ticker := time.NewTicker(time.Millisecond * 500)

    go func() {

        for t := range ticker.C {

            fmt.Println("Tick at", t)

        }

    }()



    time.Sleep(time.Millisecond * 1600)

    ticker.Stop()

    fmt.Println("Ticker stopped")

}

// 输出

// Tick at 2012-09-23 11:29:56.487625 -0700 PDT

// Tick at 2012-09-23 11:29:56.988063 -0700 PDT

// Tick at 2012-09-23 11:29:57.488076 -0700 PDT

// Ticker stopped
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档