go语言-channel使用(二十一)

1. channel介绍 

 

2. 通过channel实现同步


import (
	"fmt"
	"time"
)

var ch = make(chan int)

func Printer(str string) {

	for _, data := range str {
		fmt.Printf("%c", data)
		time.Sleep(time.Second)
	}
	fmt.Printf("\n")
}
//person1执行完成后,才能到person2执行
func person1(str string) {
	Printer(str)
	ch <- 666 //会给管道写数据,发送
}

func person2(str string) {
	<- ch //从管道取数据,接收,如果管道没有数据它就阻塞
	Printer(str)
}

func main() {
	//新建2个协程,
	go person1("hello")
	go person2("world")

	for {

	}

}

3.通过channel实现同步和数据交换

func main() {

	go func() {
		defer fmt.Printf("子协程调用完毕")

		for i:=0; i<5; i++ {
			fmt.Println("this is a new task, i=", i)
			time.Sleep(time.Second)
		}

		ch <- 123

	}()

	<- ch //没有数据前,阻塞
	fmt.Printf("主线程调用完毕")

}

channel 的类型

channel 分为不带缓存的 channel 和带缓存的 channel。

无缓存的 channel

从无缓存的 channel 中读取消息会阻塞,直到有 goroutine 向该 channel 中发送消息;同理,向无缓存的 channel 中发送消息也会阻塞,直到有 goroutine 从 channel 中读取消息。

通过无缓存的 channel 进行通信时,接收者收到数据 happens before 发送者 goroutine 唤醒

 

 

4. 无缓存的 channel

从无缓存的 channel 中读取消息会阻塞,直到有 goroutine 向该 channel 中发送消息;同理,向无缓存的 channel 中发送消息也会阻塞,直到有 goroutine 从 channel 中读取消息。

通过无缓存的 channel 进行通信时,接收者收到数据 happens before 发送者 goroutine 唤醒

5. 有缓存的 channel

有缓存的 channel 的声明方式为指定 make 函数的第二个参数,该参数为 channel 缓存的容量

 

ch := make(chan int, 10)

有缓存的 channel 类似一个阻塞队列(采用环形数组实现)。当缓存未满时,向 channel 中发送消息时不会阻塞,当缓存满时,发送操作将被阻塞,直到有其他 goroutine 从中读取消息;相应的,当 channel 中消息不为空时,读取消息不会出现阻塞,当 channel 为空时,读取操作会造成阻塞,直到有 goroutine 向 channel 中写入消息。


 

func main() {
   	//创建一个有缓存到channel
	var ch = make(chan int, 5)

	go func() {
		for i:=0; i< 10; i++ {
			ch <- i
			fmt.Println("this is new task, i=", i)
			time.Sleep(time.Second*2)
		}
	}()


	for m:=0; m<10; m++ {
		fmt.Println("this is main task, m=", m)
		<- ch
		//time.Sleep(time.Second)
	}

}

6. 关闭channel

7. 通过range遍历channel内容


func main() {

	var ch = make(chan int, 5)

	go func() {
		for i:=0; i<10; i++ {
			ch <- i
		}
		close(ch)
		fmt.Println("new task is closed")
	}()

	for {
        //通过range遍历channel内容
		for num := range ch {
			fmt.Println("rum=", num)
		}

	}

}

8.  单方向的channel

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值