go-基础-channels

package main

import (
	"fmt"
	"time"
)

func worker(done chan bool) {
	fmt.Println("working...")
	time.Sleep(time.Second)
	fmt.Println("done")
	done <- true // 写入信息到管道内
}

func ping(pings chan<- string, msg string) {
	// 这里pings是输入
	pings <- msg
}
func pong(pings <-chan string, pongs chan<- string) {
	msg := <-pings // 这里pings是输出
	pongs <- msg
}
func main() {
	message := make(chan string)      // 传建一个频道管道,内容类型是字符串
	go func() { message <- "ping" }() // 执行发送ping到管道上
	msg := <-message                  // 接收管理上的值并赋值给msg
	fmt.Println(msg)                  // 打印管道内容

	// 缓冲两个值
	msg2 := make(chan string, 2) // 设置两个对话的管道
	msg2 <- "buffered"           // 发送信息到管道
	msg2 <- "channel"
	fmt.Println(<-msg2) // 取出信息
	fmt.Println(<-msg2)

	// 通知工作完成
	done := make(chan bool, 1)
	go worker(done)
	<-done // 获取管道信息

	// 发送和接收
	pings := make(chan string, 1)
	pongs := make(chan string, 1)
	ping(pings, "hello chan") // 输入pings接收方管道
	pong(pings, pongs)        // 从接收方管道读取输出到结果方管道
	fmt.Println(<-pongs)      // 从结果管理取出数据

	// 获取异步信息
	c1 := make(chan string)
	c2 := make(chan string)
	go func() {
		time.Sleep(2 * time.Second)
		c1 <- "hello11" // 输入两次,则可读取两次
		c1 <- "hello22"
	}()
	go func() {
		time.Sleep(1 * time.Second)
		c2 <- "world"
	}()

	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-c1:
			fmt.Println("received1", msg1)
		case msg2 := <-c2:
			fmt.Println("received2", msg2)
		}
	}
	fmt.Println("received1 out", <-c1) // <-里面如果为空只会报错

	// 超时,一个超时一个不超时的例子
	c3 := make(chan string, 1)
	go func() {
		time.Sleep(2 * time.Second)
		c3 <- "result 1"
	}()
	select {
	case res := <-c3:
		fmt.Println(res)
	case <-time.After(1 * time.Second): // 超时1s
		fmt.Println("timeout 1")
	}
	c4 := make(chan string, 1)
	go func() {
		time.Sleep(2 * time.Second)
		c4 <- "result 2"
	}()
	select {
	case res := <-c4:
		fmt.Println(res)
	case <-time.After(time.Second * 3):
		fmt.Println("timeout 2")
	}

	// 使用default实现非阻塞,不写默认处理会阻塞成为死锁。
	msg5 := make(chan string)
	signals := make(chan string)
	select {
	case msg := <-msg5:
		fmt.Println(msg)
	default:
		fmt.Println("no msg received")
	}
	msgStr1 := "hi"
	select {
	case msg5 <- msgStr1:
		fmt.Println("sent message", msg)
	default:
		fmt.Println("no meg sent")
	}
	select {
	case msg := <-msg5:
		fmt.Println("receive msg", msg)
	case sig := <-signals:
		fmt.Println("receive signal", sig)
	default:
		fmt.Println("no activity")
	}
	// 关闭管道:表示不会在其上发送更多值
	jobs := make(chan int, 5)
	done2 := make(chan bool)
	go func() {
		for { // 一直监听jobs的值
			j, more := <-jobs
			if more {
				fmt.Println("received job", j)
			} else {
				fmt.Println("receive all jobs")
				done2 <- true
				return
			}
		}
	}()
	for i := 0; i < 3; i++ {
		jobs <- i // 发送值给jobs
		fmt.Println("sent job", i)
	}
	close(jobs) // 关闭管道,发送完毕
	fmt.Println("sent all jobs")
	<-done2
	// 缓存管道
	queue := make(chan string, 2)
	queue <- "one"
	queue <- "two"
	close(queue)
	for elem := range queue {
		fmt.Println("elem", elem)
	}

	// 定时器
	timer := time.NewTimer(2 * time.Second)
	<-timer.C
	fmt.Println("Time. 1 fired")

	timer2 := time.NewTimer(time.Second)
	go func() {
		<-timer2.C
		fmt.Println("timer2 2 fired")
	}()
	stop2 := timer2.Stop()
	if stop2 {
		fmt.Println("t2 stop", stop2)
	}
	time.Sleep(2 * time.Second)

	// 延时器
	ticker := time.NewTicker(500 * time.Microsecond)
	done4 := make(chan bool)
	go func() {
		for { // 内部循环,终止循环的钥匙放在另一个管理里面。
			select {
			case <-done4:
				return
			case t := <-ticker.C:
				fmt.Println("tick at", t)
			}
		}
	}()

	time.Sleep(1600 * time.Millisecond)
	ticker.Stop()
	done4 <- true // 类似于 resolve(true), 来当做是一个停止管理去操作
	fmt.Println("ticker stopped")
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值