您可以使用
select和频道杀死无限循环!
var quit chan struct{}func startLoop() { quit := make(chan struct{}) go loop()}func stopLoop() { // As mentioned by Kaedys //close(quit) // permits signalling everyone havins such a `case <-quit:` // statement to be stopped at once, which might be even better. quit <- struct{}{}}// BTW, you cannot call your function main, it is reservedfunc loop() { for { select { case <-quit: return # better than break default: // do stuff. I'd call a function, for clarity: do_stuff() } }}很不错的Go交换,不是吗?
现在,这有什么奇怪的地方
chan struct{}?这是一个零尺寸的频道。我们只能用空结构填充它(即:)struct{}{}。可能是a chanbool或其他,因为我们不使用频道的内容。重要的是,我们使用
quit通道通知goroutine中的无限循环,该该停止了。
该
select语句用于捕获来自渠道的内容。这是一条阻塞语句(
case除非您放置一条
default语句,否则它将停止执行,直到在所调查的通道之一中放入某些内容为止)。在这种情况下,每次
select执行时,如果将某些内容放入
quit或
do_stuff()将被调用,则循环将中断。如果您去过Go
Tour,那么您已经知道这一点。
其他很酷的并发模式可以在Go Blog中找到。
最后,为了获得更多的乐趣,您可以
do_stuff使用
Tickers 来要求您的函数在固定的时间间隔执行,而不是像这样消耗100%的CPU:
import "time"// [...]func loop() { // This ticker will put something in its channel every 2s ticker := time.NewTicker(2 * time.Second) // If you don't stop it, the ticker will cause memory leaks defer ticker.Stop() for { select { case <-quit: return case <-ticker.C: // do stuff. I'd call a function, for clarity: do_stuff() } }}select由于我们删除了该
default语句,因此此处处于阻塞状态。



