Golang:select语句在不应该退出时退出
我正在尝试创建一个程序,分别每3、8和24秒打印一次吃饭、工作和睡眠。这是我的密码:Golang:select语句在不应该退出时退出,select,go,channel,channels,Select,Go,Channel,Channels,我正在尝试创建一个程序,分别每3、8和24秒打印一次吃饭、工作和睡眠。这是我的密码: package main import ( "fmt" "time" ) func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings ch := make(chan string) // buffered/unbuffered? go func()
package main
import (
"fmt"
"time"
)
func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings
ch := make(chan string) // buffered/unbuffered?
go func() {
for {
msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text
ch <- msg
time.Sleep(delay) // waits according to specification
}
}()
return ch
}
func main() {
ch1 := Remind("Eat", 1000*1000*1000*3) // every third second
ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second
ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
它的问题是,在打印完Eat之后,它会立即停止运行。在我读过的其他示例中,select语句将永远持续下去。为什么现在还没有呢?我不知道你从哪里读到,select将永远持续下去,但它没有 执行案例后,select语句就完成了。如果案例中指定的任何通信操作都无法继续,并且没有默认分支,则select将阻止任何com。行动可以继续。但一旦执行了案例,select就不会重复 请阅读规范中的相关章节: 把它放在一个无穷无尽的世界里,让它永远重复:
for {
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
您可能还想查看用于类似于提醒功能的任务的类型。我不知道您在哪里读到“选择”会永远持续,但它不会 执行案例后,select语句就完成了。如果案例中指定的任何通信操作都无法继续,并且没有默认分支,则select将阻止任何com。行动可以继续。但一旦执行了案例,select就不会重复 请阅读规范中的相关章节: 把它放在一个无穷无尽的世界里,让它永远重复:
for {
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
您可能还想查看类似于提醒功能的任务类型。在Go中选择与开关控制语句类似,有时称为通信开关。select侦听通道上的传入数据,但也可能存在在通道上发送值的情况。在一个单词中,select用于获取或发送并发执行的goroutine上的值
在您的示例中,因为您在主goroutine中执行当前时间,所以它总是被执行。但是,由于其他goroutine是在select语句中执行的,因此这些goroutine并不总是有机会被执行,因为一旦执行了一个case,通道块就会被执行
选择什么:
如果全部被阻止,它将等待一个进程继续
如果多个可以继续,它将随机选择一个。
当所有通道操作都无法继续且存在default子句时,将执行此操作:默认值始终是可运行的,即:准备执行。
在带有默认大小写的select语句中使用send操作可以保证发送是非阻塞的
要永远运行,请在for循环中使用它:
package main
import (
"fmt"
"time"
)
func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings
ch := make(chan string) // buffered/unbuffered?
go func() {
for {
msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text
ch <- msg
time.Sleep(delay) // waits according to specification
}
}()
return ch
}
func main() {
ch1 := Remind("Eat", 1000*1000*1000*3) // every third second
ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second
ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second
for {
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
}
Go中的select大部分类似于开关控制语句,有时称为通信开关。select侦听通道上的传入数据,但也可能存在在通道上发送值的情况。在一个单词中,select用于获取或发送并发执行的goroutine上的值
在您的示例中,因为您在主goroutine中执行当前时间,所以它总是被执行。但是,由于其他goroutine是在select语句中执行的,因此这些goroutine并不总是有机会被执行,因为一旦执行了一个case,通道块就会被执行
选择什么:
如果全部被阻止,它将等待一个进程继续
如果多个可以继续,它将随机选择一个。
当所有通道操作都无法继续且存在default子句时,将执行此操作:默认值始终是可运行的,即:准备执行。
在带有默认大小写的select语句中使用send操作可以保证发送是非阻塞的
要永远运行,请在for循环中使用它:
package main
import (
"fmt"
"time"
)
func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings
ch := make(chan string) // buffered/unbuffered?
go func() {
for {
msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text
ch <- msg
time.Sleep(delay) // waits according to specification
}
}()
return ch
}
func main() {
ch1 := Remind("Eat", 1000*1000*1000*3) // every third second
ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second
ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second
for {
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
}
那一定是误会了什么。谢谢@Sandi最有可能的情况是,如果通信操作无法继续,select会一直等待,如果需要的话。但它不会重复。所以你的意思是,例如,如果所有频道都是空的,select将等待?@Sandi Yes,类似的东西。例如,永远选择{}块。一定是误解了什么。谢谢@Sandi最有可能的情况是,如果通信操作无法继续,select会一直等待,如果需要的话。但它不会重复。所以你的意思是,例如,如果所有频道都是空的,select将等待?@Sandi Yes,类似的东西。例如,永远选择{}块。谢谢你的回答。通道阻塞意味着什么?我很难找到它的定义。谢谢你的回答。通道阻塞意味着什么?我很难找到它的定义。