Go 在选择{case:channel}中更改频道
我使用一个Ticker定期执行任务,但在更改它时遇到了一些问题。收到一些消息后,我会将股票代码更改为新的,并更改时间间隔。下面是将重新处理此问题的示例代码:Go 在选择{case:channel}中更改频道,go,channel,Go,Channel,我使用一个Ticker定期执行任务,但在更改它时遇到了一些问题。收到一些消息后,我会将股票代码更改为新的,并更改时间间隔。下面是将重新处理此问题的示例代码: package main import ( "fmt" "time" ) type A struct { ticker *time.Ticker } func (a *A) modify() { a.ticker.Stop() a.ticker = time.NewTicker(time.Sec
package main
import (
"fmt"
"time"
)
type A struct {
ticker *time.Ticker
}
func (a *A) modify() {
a.ticker.Stop()
a.ticker = time.NewTicker(time.Second)
}
func main() {
a := new(A)
a.ticker = time.NewTicker(time.Second)
go func() {
for {
select {
case <-a.ticker.C:
fmt.Println("now")
go a.modify()
/*
default:
//fmt.Println("default")
time.Sleep(time.Millisecond * 100)
*/
}
}
}()
time.Sleep(time.Second * 60)
}
主程序包
进口(
“fmt”
“时间”
)
类型A结构{
ticker*time.ticker
}
func(a*a)modify(){
a、 股票代码停止()
a、 ticker=time.NewTicker(time.Second)
}
func main(){
a:=新的(a)
a、 ticker=time.NewTicker(time.Second)
go func(){
为了{
挑选{
case问题在于goroutine是异步运行的。
使用a.modify()
时,代码的行为如下:
从a.ticker.C
停止旧的ticker,并创建新的a.ticker.C
使用选择
在这种情况下,2.中新创建的a.ticker.C
与3.中的频道等待相同
如果你在goroutine中做2。它可以按照以下顺序进行
从a.ticker.C
使用选择
停止旧的ticker,并创建新的a.ticker.C
在这种情况下,2.中等待的通道与3.中新创建的通道不同。
由于选择频道是一个被停止的旧频道,所以它永远不会得到任何滴答声
您可以通过插入一些fmt.Printf
来确认此行为,并查看a.ticker.C
的地址
func (a *A) modify() {
a.ticker.Stop()
fmt.Printf("ticker stopped: %p\n", &a.ticker.C)
a.ticker = time.NewTicker(time.Second)
fmt.Printf("new ticker created: %p\n", &a.ticker.C)
}
func main() {
a := new(A)
a.ticker = time.NewTicker(time.Second)
go func() {
for {
fmt.Printf("waiting for ticker: %p\n", &a.ticker.C)
select {
....
使用a.modify()
:
使用转到a.modify()
:
您可以看到,使用go a.modify()
时,您并不是在等待新创建的频道
默认行为的更新:
将默认值:
与go a.modify()
一起使用时,其行为如下
等待a.ticker.C
,打勾,调用go a.modify()
,它执行3
等待a.ticker.C
,什么也得不到,所以返回默认值并睡眠100毫秒
停止旧的ticker,更新a.ticker.C
等待a.ticker.C
,什么也得不到,所以返回默认值并睡眠100毫秒
等待a.ticker.C
,什么也得不到,所以返回默认值并睡眠100毫秒
等待a.ticker.C
,什么也得不到,所以返回默认值并睡眠100毫秒
等待a.ticker.C
,打勾,调用go a.modify()
关键是,{}
的循环可以继续进行,即使您从a.ticker.C
中什么都没有得到。
您可以使用相同的代码确认该行为
waiting ticker: 0xc420010100 <-- 1.
now <-- 1.
waiting ticker: 0xc420010100 <-- 2.
default <-- 2.
ticker stopped: 0xc420010100 <-- 3.
new ticker created: 0xc420066240 <-- 3.
waiting ticker: 0xc420066240 <-- 4.
default <-- 4.
waiting ticker:0xc420010100明白了!那么为什么默认情况也可以解释一下
waiting for ticker: 0xc420010100
ticker stopped: 0xc420010100
new ticker created: 0xc420068000
waiting for ticker: 0xc420068000
ticker stopped: 0xc420068000
new ticker created: 0xc420068080
waiting for ticker: 0xc420068080
waiting for ticker: 0xc420010100
waiting for ticker: 0xc420010100
ticker stopped: 0xc420010100
new ticker created: 0xc420066040
waiting ticker: 0xc420010100 <-- 1.
now <-- 1.
waiting ticker: 0xc420010100 <-- 2.
default <-- 2.
ticker stopped: 0xc420010100 <-- 3.
new ticker created: 0xc420066240 <-- 3.
waiting ticker: 0xc420066240 <-- 4.
default <-- 4.