Golang 协程配合管道

请完成goroutine和channel协同工作的案例,具体要求:
(1)开启一个writeData协程,向管道mtChan中写入50个整数.
(2)开启一个readData协程,从管道intChan中读取writeData写入的数据。
(3)注意:writeData和readDate操作的是同一个管道
(4)主线程需要等待writeData和readDate协程都完成工作才能退出(如果主线程不做处理,那么其他线程还没干完活就直接跑路了)

管道是引用类型,那么写入读取的都是同一个管道,也就是在不同函数不同栈里面读取的都是同一个管道。两个协程同时的向管道里面写入读取数据,而不是一个写完另外一个协程再去读取。

Golang 协程配合管道_第1张图片

package main

import (
	"fmt"
)

func writeData(initChan chan int) {
	for i := 0; i <= 50; i++ {
		//放入数据
		initChan <- i
		fmt.Println("write data:", i)
	}
	close(initChan)
}
func readData(initChan chan int, exitChan chan bool) {
	//即使管道close之后并不影响读取,当在管道当中取不到数据才会退出
	for {
		//在从一个管道里面读取会返回两个值,ok是有没有正确读取到
		v, ok := <-initChan
		if !ok {
			break
		}
		fmt.Println("read data:", v)
	}
	//readData任务完成之后
	exitChan <- true
	close(exitChan)
}

func main() {
	//创建两个管道
	initChan := make(chan int, 50)
	exitChan := make(chan bool, 1)

	go writeData(initChan)
	go readData(initChan, exitChan)

	for {
		_, ok := <-exitChan
		fmt.Println("ok=", ok)
		if ok {
			break
		}
	}
}

如果给的容量就是50,那么循环50次就刚好放进去了。如果管道和放进去的数据量不匹配,管道的容量小于放进去的数据,又不取出来,那么它就会阻塞,阻塞就会死锁。

这个管道可以容纳的数据量很小,要写的数据量很大,只要一边在写,另外一边在读是无所谓的。

如果写的快,读取的慢。那么在写的时候就会阻塞,编译器会发现虽然阻塞了,但是有另外一个协程在往里面读取数据,这样就不会发生死锁。

死锁编译器底层会分析,如果发现一个地方在不停的写,但是没有任何一个协程去读取这样就直接死锁,如果有一个协程在慢慢的读取这样不会死锁。和写入读取速度没有关系,但是必须有写入的协程和读取的协程。简而言之就是管道需要不停的流动

Golang 协程配合管道_第2张图片

你可能感兴趣的:(Go,Goroutines,和,Channels,golang)