Golang:select语句在不应该退出时退出

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()

我正在尝试创建一个程序,分别每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() {
        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,类似的东西。例如,永远选择{}块。谢谢你的回答。通道阻塞意味着什么?我很难找到它的定义。谢谢你的回答。通道阻塞意味着什么?我很难找到它的定义。