`

go语言goroutine的通信机制(二)

    博客分类:
  • Go
 
阅读更多
package main
import "fmt"
/*

管道Channel是goroutine间的通讯方式,可以使用channel在多个goroutine之间传递消息

golang的并发模型是CSP,提倡通过通信共享内存,而不是通过共享内存实现通信

1.管道的类型,是引用数据类型
2.如果创建管道的时候没有指定容量,那么这个管道就是无缓冲的管道,由称为阻塞管道
3.如果管道满了,你还往管道存储数据,会报deadlock错
4.在没有使用协程的情况下,如果我们的管道数据已经全部取出,再取就会报deadlock错,

*/


func main() {
//	创建管道
	ch:= make(chan int, 3)
//	给管道里存数据
	ch<-10
	ch<-20
	ch<-30
    //从管道里取值
	a:=<- ch
	fmt.Println(a)   //10

	<-ch
	c:=<-ch
	fmt.Println(c)   //30

	fmt.Printf("值:%v 容量:%v 长度:%v\n", ch, cap(ch),len(ch))  //值:0x820238000 容量:3 长度:0



	//使用for range遍历管道,当管道被关闭的时候就会退出for range,如果没有关闭管道就会报错
	//all goroutines are asleep - deadlock!

	var ch1 = make(chan int ,10)

	for i:=1;i<=10;i++{
		ch1<-i
	}
	close(ch1)  //关闭管道

	//注意管道没有key
	for v := range ch1{
		fmt.Println(v)
	}

	//注意:通过for循环遍历管道可以不关闭管道,for range遍历必须关闭,否则报错
	var ch2 = make(chan int ,10)

	for i:=1;i<=10;i++{
		ch2<-i
	}
//	close(ch1)  //关闭管道

	
	for i:=1;i<=10;i++{
		fmt.Println(<-ch2)
	}


}
package main
import "fmt"
import "sync"
import "time"

/*
goroutine结合channel协同工作,定义两个方法,一个方法给管道写数据,一个从管道里读数据

管道是安全的:如果一个管道读取数据的速度比写入数据的速度快,读取不会报错

*/

var wg sync.WaitGroup

func fn1(ch chan int){
	for i:=1;i<=10;i++{
		ch<-i
		fmt.Printf("写入数据%v成功\n", i)
		time.Sleep(time.Millisecond*10)  //为了看出交替执行的效果
	}
	close(ch)
	wg.Done()
}


func fn2(ch chan int){
	for v := range ch{
		fmt.Printf("读取数据%v成功\n", v)
		time.Sleep(time.Millisecond*10)  //为了看出交替执行的效果
	}
	wg.Done()
}



func main() {
	var ch = make(chan int, 10)
	wg.Add(1)
	go fn2(ch)
	wg.Add(1)
	go fn1(ch)

	wg.Wait()

}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics