Golang Go语言中Channel学习的一个疑问,请大佬指教
Golang Go语言中Channel学习的一个疑问,请大佬指教
func main() {
boolChannel()
}
func boolChannel() {
ch1 := make(chan int)
ch2 := make(chan bool)
go func() {
for i:=0;i<5;i++ {
ch1 <- i
}
ch2 <- true //标识位写入 true
}()
go func() {
for x:= range ch1{
fmt.Println(x)
}
}()
<-ch2 //阻塞标识位
}
为什么这个输出结果一会是 0,1,2,3,一会是 0,1,2,3,4
按道理来说,我在主进程一直阻塞了,应该等 goroutine 全部打印完才对呀,百思不得其解
更多关于Golang Go语言中Channel学习的一个疑问,请大佬指教的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
应该是 fmt.Println(x)这里的耗时吧,ch1 <- 4 完了之后马上 ch2 <- true,主协程一直阻塞后马上执行<-ch2,这时候 fmt.Println(4)这里卡在主协程结束前后,所以会有不稳定的情况
我的理解是这样
更多关于Golang Go语言中Channel学习的一个疑问,请大佬指教的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这不是很正常啊 打印的 goroutine 你有没有同步机制 去保证 先于 main goroutine 结束 ?
去看看 GMP 的调度把
ch2 <- true 上面加一行 time.Sleep(1 * time.Second)
<-ch2 接受到值,就往后执行了,这时候第二个 goroutine 可能还没执行完成
删掉 ch2 <- true 就可以了
打印完后再往 ch2 写值
加入 wait group 或者 context,不能保证你的 print 在 main 之前
这两个 go 出去的 func 并没有形成锁,只有第一个 func 和 boolChannel 形成了锁,所以你能确保的是全部写入后才会终结 boolChannel 的执行,但 fmt.Println(x)一定执行吗?不一定,因为可能正准备 fmt.Println(x),这个 goroutine 就被切到等待队列里了
(我不知道应不应该使用锁这个名词,基础忘掉了大半,欢迎拍砖)
第一个 go 协程结束时关闭信道
第二个协程直接在主线程执行。
ch2 可以去掉。
ch2 <- true 改成 close(ch1)
ch2 <- true 移到第二个 for 后面
大佬牛逼
4 进入 ch1 后,true 进入 ch2,
情况 1:主程序先得到 ch2,第二个 func 还没来得及得到 ch1 或者没来得及打印, 程序就退出 输出 0,1,2,3
情况 2:第二个 func 得到 ch1 并且打印,主程序还没来得及得到 ch2,输出 0,1,2,3,4
ch2 <- true //标识位写入 true
这句放到第二个 func 后面就行了
通俗易懂理解了,其实就是想看看不通过 waitGroup 能不能解决,多谢~
可以的,按照云风大侠的说法,通道是最佳解决方案
一般是发送 goroutine 是 close 发送的 chan,接收 goroutine 是关闭阻塞 chan
这样的好处是不会造成 goroutine 泄露,发送完 close,接收 for chan 还是可以接收完数据的,会自己退出,这时候 close 或者发送信号到退出 chan 。
在Go语言中,Channel是用于在不同的goroutine之间进行通信的重要机制。关于你在学习Channel时遇到的疑问,我可以提供以下几点指导:
-
Channel的基本概念:Channel是一种类型安全的管道,允许你在goroutine之间发送和接收数据。它确保了数据发送和接收的同步性,避免了数据竞争和死锁等问题。
-
Channel的创建与操作:你可以使用
make
函数来创建一个Channel,例如ch := make(chan int)
。发送数据到Channel使用<-
操作符,如ch <- 42
;从Channel接收数据也使用<-
操作符,如value := <-ch
。 -
Channel的阻塞特性:发送数据到无缓冲Channel时,如果接收方未准备好接收,发送操作将阻塞;同样,从无缓冲Channel接收数据时,如果发送方未发送数据,接收操作也会阻塞。有缓冲Channel则根据缓冲区的情况决定是否阻塞。
-
关闭Channel:使用
close(ch)
可以关闭一个Channel,表示没有更多的值会被发送到Channel。接收方可以通过检测语法v, ok := <-ch
来判断Channel是否已关闭。 -
选择语句(select):在多个Channel上进行操作时,可以使用
select
语句来等待多个Channel的通信操作。
如果你有更具体的疑问或遇到了特定的代码问题,请提供更详细的描述,这样我可以给出更针对性的解答。希望这些信息对你有所帮助!