GO通道练习

package learnChannel

import (
	"fmt"
	"sync"
)

/*
	单纯让函数并发是没有意义的,函数与函数之间需要交换数据才能体现函数并发的意义
	虽然可以使用共享内存进行数据交换,但共享内存在不同的goroutine中容易发生竞态问题(资源竞争),为了保证数据交换的正确性
	必须使用互斥锁进行枷锁,但这样做会造成资源的浪费
	Go语言的并发模型是CSP 提倡通过通信共享内存而不是通过共享内存实现通信
	如果说goroutine是Go程序的并发执行体,channel就是他们的连接,channel是可以让一个goroutine发生特定值到另一个goroutine的通信机制
	Go语言中的通道是一种特殊类型,像一个传送带或者队列,总是遵循先入先出的规则,保证收发数据的顺序
	每一个通道都是一个具体类型的导管,声明channel的时候需要为其指定元素类

	var 变量 chan 元素类型
 */


var _ []int
var b chan int // 需要指定通道中元素的类型  他是一个引用类型,需要初始化才能使用
var wg sync.WaitGroup

func NoBuffChannel(){
	//wg.Add(1)
	fmt.Println(b)
	b = make(chan int,2) //初始化一个带缓冲区的通道
	//go func() {
	//	defer wg.Done()
	//	res := <-b
	//	fmt.Println(res)
	//}()

	fmt.Println("数值发送到通道里面了")
	b <- 10 // 带缓冲区不会导致死锁

	b <- 20
	x := <- b
	fmt.Println(b)
	fmt.Println(x)
	x = <- b
	fmt.Println(x)
	close(b)
	//wg.Wait()


}

/*
		<-
	发送: ch1 <- 1 把1放到通道里面
	接收: res := <- ch1 把通道1里面的数赋值给res
	关闭: close
 */
func action(){
	wg.Add(1)
	fmt.Println(b)
	b = make(chan int) // 初始化一个不带缓冲区的通道 这会导致没办法接收对方的信息
	//b = make(chan int,100) //初始化一个带缓冲区的通道
	go func() {
		defer wg.Done()
		res := <-b
		fmt.Println(res)
	}()

	fmt.Println("数值发送到通道里面了")
	b <- 10 // all goroutines are asleep - deadlock! 因为没有缓冲区接受所以导致死锁了

	fmt.Println(b)
	wg.Wait()
}



package learnChannel

import (
	"fmt"
	"sync"
)

//如果对一个已关闭的通道取值是可以的,只不过返回的OK是一个false 取值是通道类型的0值

var once sync.Once
func f1(ch1 chan int){
	// 开启goroutine 将0~100的数据塞去channel中
	defer wg.Done()
	for i:=0;i<100;i++{
		ch1 <- i
	}
	close(ch1)
}

func f2(ch1,ch2 chan int){
	defer wg.Done()
	// 开启goroutine从ch1中接受值,并将该值的平方发送到ch2中 这里有可能ch1里面没有值
	for {
		x,ok := <- ch1
		if !ok{
			break
		}
		ch2 <- x*x
	}
	//确保某个操作只执行一次 原子的操作
	once.Do(func() {close(ch2)})
}

func Excel_channel(){
	ch1 := make(chan int,50)
	ch2 := make(chan int,100)
	wg.Add(3)
	go f1(ch1)
	go f2(ch1,ch2)
	go f2(ch1,ch2)
	wg.Wait()
	for ret := range ch2{
		fmt.Println(ret)
	}

}

package learnChannel

import "time"

/*
	单向通道 一般用于参数,代表某个通道只能取值或者塞入
 */


// 代表只能塞入
func LearnSingalChannel(ch1 chan <- int){
	time.Tick(time.Second) // 定时器

}

//代表只能获取
func LearnSingalChannel2(ch2   <- chan int){

}

channelnil非空空的满了没满
接收阻塞接收成功阻塞接收值接受值
发送阻塞发送值发送值阻塞发送值
关闭panic关闭成功,读取完数据后返回0值关闭成功,返回0值关闭成功读完数据后返回0值关闭成功读完数据后返回0值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值