flora222

GoLangStudy:day10

GOday10

golang语法基础(channel管道part1)

1.channel的基本定义与使用

示例:

package main

import "fmt"

func main() {
	//定义一个无缓存channel,接收int类型的值
	c := make(chan int)
	go func() {
		defer fmt.Println("goroutine 结束")
		fmt.Println("goroutine正在运行")
		c <- 666 //将666发送给c管道
	}()

	num := <-c //从c中接受数据并赋值给num
	//<-c,意思是读取c管道中的值,然后抛弃掉
	fmt.Println("num =", num)
	fmt.Println("main goroutine 结束")
}

输出结果:

goroutine正在运行
goroutine 结束
num = 666
main goroutine 结束

channel可以将两个不同步的goroutine连接起来:

上面示例代码中,主协程和分协程的运行是不同步的,那么连接两个协程的关键语句就是主协程中的num := <-c和分协程中的c <- 666

1,当主协程运行到num := <-c而分协程没有运行到c <- 666时,主协程会发生阻塞,直到分协程运行到管道部分,阻塞才会解除

2,反之亦然,分协程先运行到管道部分的时候,分协程的阻塞也会发生,并在主协程运行到管道部分时解除

2.channel有缓冲与无缓冲同步问题

无缓冲channel:(与上文代码原理一致)

屏幕截图 2026-07-17 232013

有缓冲channel

屏幕截图 2026-07-17 232615

在有缓冲情况下,若通道内存储满了,则发送方会发生阻塞,直到接收方取值为管道腾出空间

​ 反之亦然,若通道内空了,则接收方会发生阻塞,直到发送方传入新的值

示例:

package main

import (
	"fmt"
	"time"
)

func main() {
	//创建一个有缓存channel,容量为3
	c := make(chan int, 3)

	//len表示管道c中存储的数据个数,cap表示管道c的总容量
	fmt.Println("len(c)=", len(c), ", cap(c)=", cap(c))

	go func() {
		defer fmt.Println("子协程结束")

		for i := 0; i < 3; i++ {
			c <- i
			fmt.Println("子协程正在运行,发送的元素i=", i, "len(c)=", len(c), ", cap(c)=", cap(c))
		}

	}()

	time.Sleep(2 * time.Second)

	for i := 0; i < 3; i++ {
		num := <-c //从c中接受数据,并赋值给num
		fmt.Println("num=", num)
	}
	fmt.Println("main 结束")
}

输出结果:

len(c)= 0 , cap(c)= 3
子协程正在运行,发送的元素i= 0 len(c)= 1 , cap(c)= 3
子协程正在运行,发送的元素i= 1 len(c)= 2 , cap(c)= 3
子协程正在运行,发送的元素i= 2 len(c)= 3 , cap(c)= 3
子协程结束
num= 0
num= 1
num= 2
main 结束

3.channel的关闭特点

关闭channel示例:

package main

import (
	"fmt"
)

func main() {
	//创建一个无缓存channel
	c := make(chan int)

	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}
		//close是go的内嵌函数,可以关闭一个channel
		close(c)
	}()

	for {
        //if-else判断语句的简写方式
        //先执行data, ok := <-c,随后对ok进行判断
		if data, ok := <-c; ok {
			fmt.Println(data)
		} else {
			break
		}
	}
	fmt.Println("main 结束")
}

输出结果:

关闭channel:
0
1
2
3
4
main 结束

不关闭channel:(协程死锁,程序报错)
0
1
2
3
4
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
	D:/GoStudyProjects/demo01/main.go:20 +0xbd

channel关闭时注意事项:

屏幕截图 2026-07-18 003125

(nil channel一般不会实际使用)

posted on 2026-07-18 00:35  Flora2  阅读(4)  评论(0)    收藏  举报

导航