所以我有这个代码,它接受one
,two
或three
的用户输入。它会根据所选的持续时间打印Ticker ticked
。我需要有关如何在以不同的持续时间再次激活股票代码之前停止股票代码的帮助。
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
func main() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
text, _ := reader.ReadString('\n')
text = strings.Replace(text, "\n", "", -1)
switch text {
case "one":
go timeTick(true, 1)
case "two":
go timeTick(true, 2)
case "three":
go timeTick(true, 3)
default:
go timeTick(false, 0)
}
}
}
func timeTick(flag bool, tick int) {
var tickChan *time.Ticker
if flag {
tickChan = time.NewTicker(time.Second * time.Duration(tick))
}
doneChan := make(chan bool)
if !flag {
doneChan <- true
}
for {
select {
case <-tickChan.C:
fmt.Println("Ticker ticked")
case <-doneChan:
fmt.Println("Done")
return
}
}
}
因此,用户输入one
,two
或three
以激活其他代码,它会将true
发送到doneChan
频道。
当我使用one
激活代码时。它每秒打印Ticker ticked
但是当我在自动收报机运行时输入two
或three
时如何停止自动收报机?然后它引出了我的主要问题,为什么即使输入随机字符串也没有触发doneChan
?
答案 0 :(得分:2)
您需要传入用于信号完成的频道。如果有的话,您总是希望取消当前的自动收报机,这样您就可以在主for
循环的每次迭代中尝试发送。由于通道未缓冲,因此发送操作正在阻塞,因此您需要在具有默认情况的select语句中尝试发送,以防止在您没有当前自动收报机尝试从通道读取的情况下出现死锁
package main
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
func main() {
reader := bufio.NewReader(os.Stdin)
tickerDone := make(chan struct{})
for {
fmt.Print("> ")
text, _ := reader.ReadString('\n')
text = strings.Replace(text, "\n", "", -1)
select {
case tickerDone <- struct{}{}:
default:
}
switch text {
case "one":
go timeTick(1, tickerDone)
case "two":
go timeTick(2, tickerDone)
case "three":
go timeTick(3, tickerDone)
}
}
}
func timeTick(tick int, done <-chan struct{}) {
tickChan := time.NewTicker(time.Second * time.Duration(tick))
for {
select {
case <-tickChan.C:
fmt.Println("Ticker ticked")
case <-done:
fmt.Println("Done")
return
}
}
}
答案 1 :(得分:0)
您也可以尝试以下代码。我把缓冲通道放在函数外部进行同步执行,我还使用通道接收器来分配和停止通道。
func timeTick(flag bool, tick int,doneChan chan bool) {
var tickChan *time.Ticker
msg := make(<-chan time.Time) // channel receiver
if flag {
tickChan = time.NewTicker(time.Second * time.Duration(tick))
}
if !flag {
doneChan <- true
<-msg
}
if tickChan != nil { // Check if nil
msg = tickChan.C
}
for {
select {
case <-msg:
fmt.Println("Ticker ticked ")
case <-doneChan:
fmt.Println("Done ")
return
}
}
}
func main() {
reader := bufio.NewReader(os.Stdin)
doneChan := make(chan bool,1)
for
{
fmt.Print("> ")
text, _ := reader.ReadString('\n')
text = strings.Replace(text, "\n", "", -1)
switch text {
case "one":
go timeTick(true, 1, doneChan)
case "two":
go timeTick(true, 2, doneChan)
case "three":
go timeTick(true, 3, doneChan)
default:
go timeTick(false, 0, doneChan)
}
}
}