Golang中select语句无法通过channel发送数据的问题如何解决?
Golang中select语句无法通过channel发送数据的问题如何解决?
package main
import (
"fmt"
"time")
func useChan(dataChan <-chan string,stopchan <-chan string){
for{
select{
case <- dataChan:
fmt.Println("data Recieved")
time.Sleep(50 * time.Millisecond)
case <- stopchan:
fmt.Println("stopping")
return
default:
continue
}
}
}
func main() {
dataChan := make(chan string)
stopchan := make(chan string)
go useChan(dataChan,stopchan)
//ready := true
for timeout := time.After(5 *time.Second); ;{
time.Sleep(10 * time.Millisecond)
select{
case dataChan <-"something":
case <-timeout:
stopchan <- "stop"
fmt.Println("breaking ")
return
default:
//fmt.Println("continue")
continue
}
}
}
请帮助我
更多关于Golang中select语句无法通过channel发送数据的问题如何解决?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
尝试从 select 块中移除两个默认情况。并保持无缓冲通道。
更多关于Golang中select语句无法通过channel发送数据的问题如何解决?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你期望发生什么?实际发生了什么?是否出现错误?
我期望它能打印"数据已接收"。但它没有打印出来。运行时没有错误。
请查看关于如何在 select 语句中使用 time.After 的文档:
好的,程序运行了,但在 useChan 函数中的"data received"没有打印出来。
这是一个学习练习。存在一些逻辑错误。
// 代码部分保持原样
天啊,它居然成功了。
以下是我的理解,请告诉我是否正确:
无缓冲通道的写入操作是阻塞的,除非有协程正在从中读取。由于在 Select 语句中,当多个 case 条件为真时,case 选择是随机的,所以它选择了 default case。但我仍然不明白的是,既然选择 default 和其他通道的概率相同,为什么它甚至一次都没有从 “dataChan” 中读取过。
谢谢
在你的代码中,select 语句无法通过 channel 发送数据的问题主要源于 useChan 函数中的 default 分支。由于 default 分支的存在,当 dataChan 和 stopchan 都没有数据可接收时,useChan 函数会立即执行 default 分支并继续循环,这导致它无法及时接收来自 main 函数发送的数据。此外,main 函数中的 default 分支也导致发送操作被跳过。以下是修改后的代码示例,解决了这些问题:
package main
import (
"fmt"
"time"
)
func useChan(dataChan <-chan string, stopchan <-chan string) {
for {
select {
case <-dataChan:
fmt.Println("data Received")
time.Sleep(50 * time.Millisecond)
case <-stopchan:
fmt.Println("stopping")
return
}
}
}
func main() {
dataChan := make(chan string)
stopchan := make(chan string)
go useChan(dataChan, stopchan)
timeout := time.After(5 * time.Second)
for {
select {
case dataChan <- "something":
time.Sleep(10 * time.Millisecond)
case <-timeout:
stopchan <- "stop"
fmt.Println("breaking")
return
}
}
}
修改说明:
- 在
useChan函数中,移除了default分支。这样,select语句会阻塞等待dataChan或stopchan的数据,确保能及时接收发送的操作。 - 在
main函数中,移除了default分支和多余的continue语句。现在,select会阻塞直到dataChan发送成功或超时触发,避免了发送操作被跳过。 - 调整了超时逻辑,使用
time.After在select中直接处理超时事件。
运行此代码后,main 函数会成功通过 dataChan 发送数据,useChan 函数能正常接收并打印 “data Received”,在5秒超时后发送停止信号并退出。


