我正在使用context.Context
来控制多个goroutine。 goroutine监听context.Done()
,然后立即打印日期字符串。然后,该进程监听syscall.SIGHUP
,该操作会取消上下文,然后使用之前创建的上下文创建新的goroutine。
我认为,当syscall.SIGHUP
发出时,该过程将打印一个日期字符串,但是打印了两个。
此过程正在ubuntu18.04
上运行。
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
go printDate(ctx)
sg := make(chan os.Signal)
signal.Notify(sg, syscall.SIGHUP)
for {
select {
case <-sg:
cancel()
go printDate(ctx)
}
}
}
func printDate(ctx context.Context) {
select {
case <-ctx.Done():
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}
}
我希望输出为
2019-01-02 01:02:03
但实际输出是:
2019-01-02 01:02:03
2019-01-02 01:02:03
答案 0 :(得分:2)
cancel()
完成后,ctx
会永远保留下去。因此,当您第二次调用go printDate(ctx)
时,您将使用一个完成的Context调用printDate,并且案例可以因为ctx而运行。Done()返回一个封闭的通道,您可以从一个封闭的通道接收该信号。