使用ticker的golang代码有什么问题?

huangapple go评论81阅读模式
英文:

what's wrong with the golang code by using ticker

问题

以下是您提供的代码的翻译:

package main

import (
	"fmt"
	"time"
)

func main() {
	intChan := make(chan int, 1)
	ticker := time.NewTicker(time.Second)
	go func() {
		for _ = range ticker.C {
			select {
			case intChan <- 1:
			case intChan <- 2:
			case intChan <- 3:
			}
		}
		/*defer */
		fmt.Println("结束。[发送者]")
	}()
	var sum int
	for e := range intChan {
		fmt.Printf("接收到: %v\n", e)
		sum += e
		if sum > 10 {
			fmt.Printf("得到: %v\n", sum)
			break
			//ticker.Stop()
		}
	}
	fmt.Println("结束。[接收者]")
	//time.Sleep(10)
}

在这段代码中,您想要在 goroutine 结束时打印一次 "结束。[发送者]"。我尝试使用 ticker.Stop()time.Sleep()defer,但没有效果。请问有什么问题,给我一些想法。谢谢。

在这段代码中,问题可能出在 ticker.Stop() 的位置上。您可以尝试将 ticker.Stop() 放在 break 语句之前,如下所示:

if sum > 10 {
    fmt.Printf("得到: %v\n", sum)
    ticker.Stop()
    break
}

这样做可以确保在跳出循环之前停止 ticker。另外,您还可以使用 defer 关键字来确保在函数结束时调用 ticker.Stop(),如下所示:

defer ticker.Stop()

这样无论函数是正常结束还是发生异常,都会调用 ticker.Stop()。希望这些想法对您有帮助!

英文:
package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	intChan := make(chan int, 1)
	ticker := time.NewTicker(time.Second)
	go func() {
		for _ = range ticker.C {
			select {
			case intChan &lt;- 1:
			case intChan &lt;- 2:
			case intChan &lt;- 3:
			}
		}
		/*defer */
		fmt.Println(&quot;End. [sender]&quot;)
	}()
	var sum int
	for e := range intChan {
		fmt.Printf(&quot;Received: %v\n&quot;, e)
		sum += e
		if sum &gt; 10 {
			fmt.Printf(&quot;Got: %v\n&quot;, sum)
			break
			//ticker.Stop()
		}
	}
	fmt.Println(&quot;End. [receiver]&quot;)
	//time.Sleep(10)
}

I'm new in golang. In this code, I want print "End. [sender]" once when the goroutine is over.
I try to use ticker.stop(), or even time.sleep(), defer , but no effect.
What's wrong with it, please give me some idea. thanks

答案1

得分: 2

根据文档所说,ticker.Stop不会关闭通道,所以你不能期望它会中断循环。你可以添加一个新的通道来退出。

package main

import (
	"fmt"
	"time"
)

func main() {
	intChan := make(chan int, 2)
	ticker := time.NewTicker(time.Second)
	quit := make(chan bool)
	go func() {
	loop:
		for {
			select {
			case <-ticker.C:
				select {
				case intChan <- 1:
				case intChan <- 2:
				case intChan <- 3:
				}
			case <-quit:
				break loop
			}
		}
		/*defer */
		fmt.Println("End. [sender]")
		close(intChan)
	}()
	var sum int
	for e := range intChan {
		fmt.Printf("Received: %v\n", e)
		sum += e
		if sum > 10 {
			fmt.Printf("Got: %v\n", sum)
			quit <- true
			//break
			//ticker.Stop()
		}
	}
	fmt.Println("End. [receiver]")
	//time.Sleep(10)
}
英文:

As documentation says, ticker.Stop doesn't close channel. So you must not expect break-loop. You can add new channel for quit.

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	intChan := make(chan int, 2)
	ticker := time.NewTicker(time.Second)
	quit := make(chan bool)
	go func() {
	loop:
		for {
			select {
			case &lt;-ticker.C:
				select {
				case intChan &lt;- 1:
				case intChan &lt;- 2:
				case intChan &lt;- 3:
				}
			case &lt;-quit:
				break loop
			}
		}
		/*defer */
		fmt.Println(&quot;End. [sender]&quot;)
		close(intChan)
	}()
	var sum int
	for e := range intChan {
		fmt.Printf(&quot;Received: %v\n&quot;, e)
		sum += e
		if sum &gt; 10 {
			fmt.Printf(&quot;Got: %v\n&quot;, sum)
			quit &lt;- true
            //break
            //ticker.Stop()
		}
	}
	fmt.Println(&quot;End. [receiver]&quot;)
	//time.Sleep(10)
}

huangapple
  • 本文由 发表于 2017年6月28日 11:12:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/44793019.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定