loops - 是否可以从外部函数中停止代码/goroutine?
问题描述
所以,我有这个(只是一个例子):
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
for {
select {
case <-ticker.C:
fmt.Println("hello")
}
}
}
这是一个无限循环,我想要这样。在实际代码中,它每 1 小时循环一次。但是,如果我想调用一个函数来让它停止循环呢?这可能吗?就像是:
func stop() {
//this will stop the main function from looping
}
我知道我可以做类似的事情:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
done := make(chan bool)
go func() {
for {
select {
case <-done:
fmt.Println("done")
ticker.Stop()
return
case <-ticker.C:
fmt.Println("hello")
}
}
}()
time.Sleep(10 * time.Second)
done <- true
}
但这将从预定义的时间范围(在本例中为 10 秒)停止该函数,这不是我想要的,而且这都在同一个函数中,我需要从主函数外部进行调用。
这有可能吗?
解决方案
这里:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func stop(ch chan<- struct{}) {
select {
// Triggers after 7 seconds
case <-time.After(7 * time.Second):
ch <- struct{}{}
}
}
func signalStop(ch chan<- struct{}) {
// Use a buffered channel (size = 1)
sig := make(chan os.Signal, 1)
// Use SIGINT signal i.e., <kill -SIGINT XXXX> or <Control+C>
signal.Notify(sig, syscall.SIGINT)
select {
// Capture the SIGINT signal
case <-sig:
// Close the channel
close(ch)
}
}
func main() {
ticker := time.NewTicker(1 * time.Second)
done := make(chan struct{})
// Spawn a goroutine with the done channel
go signalStop(done)
for {
select {
case <-ticker.C:
fmt.Println("Hello!")
case <-done:
// When stop signals, stop the ticker and return
ticker.Stop()
fmt.Println("Bye, bye!")
return
}
}
}
我已经注释了代码的相关部分,以便您了解我想要做什么。
推荐阅读
- android - Shopify 的移动购买 SDK 支持缓存崩溃应用程序
- plsql - 将xml数据插入oracle表时如何解决“文件或LOB操作FILEOPEN失败”?
- ios - 共享 NSHTTPCookieStorage 会将持久性 cookie 同步到 WKWebsiteDataStore defaultDataStore httpCookieStore?
- mysql - 为什么 PHP artisan migrate 命令显示错误?
- php - form action 和 post 方法如何一起工作?
- ms-access - 如何对sql查询引用组中的多列求和
- mongodb - Mongo 查询将值推送到数组,该数组本身是另一个数组的元素
- stm32 - STM32F1x 异常、优先级和 NVIC
- algorithm - WPL树算法实现
- ruby - 为什么 state_machine 的事件没有在模型回调时触发?