golang中多goroutine时kill信号接收的问题

本文探讨的问题:外部的kill信号能被多线程程序中的多个线程同时接收到吗?

结论

可以,这里用 golang 进行举例,多个goroutine通过 signal.Notify 注册消息的接收,然后在每个 goroutine 中都可以捕捉到kill的信号

实验样例
package main

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

var wg = &sync.WaitGroup{}

func main() {
	wg.Add(2)

	go func() {
		c1 := make(chan os.Signal, 1)
		signal.Notify(c1, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
		fmt.Printf("goroutine 1 receive a signal : %v\n\n", <-c1)
		wg.Done()
	}()

	go func() {
		c2 := make(chan os.Signal, 1)
		signal.Notify(c2, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
		fmt.Printf("goroutine 2 receive a signal : %v\n\n", <-c2)
		wg.Done()
	}()

	wg.Wait()
	fmt.Printf("all groutine done!\n")
}

运行结果如下:
在这里插入图片描述
样例解释
样例中使用两个goroutine分别注册了3个信号的监听,然后程序运行之后,使用 Ctrl + C 终止程序运行,看到输出结果,两个groutine都捕捉到信号,并完成了退出

为什么要做这个实验

生产环境中,我们可能用到的别人的SDK,在别人SDK中如果实现了类似于优雅退出的操作或者其他一些要使用到signal.Notify这种注册监听的用法,我经常怀疑,这个kill信号最终是谁接收到的,这里发现所有注册的就能接收到这个信号,可以称之为广播信号。

验证接收信号的顺序

在上面得到的结论是都能捕捉到kill信号,继续验证谁先捕捉到。

样例

package main

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

var wg = &sync.WaitGroup{}

func main() {
	//用来保证注册的先后顺序
	order := make(chan int)
	wg.Add(2)

	go func() {
		c1 := make(chan os.Signal, 1)
		signal.Notify(c1, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
		order <- 1
		fmt.Printf("goroutine 1 receive a signal : %v\n\n", <-c1)
		wg.Done()
	}()

	go func() {
		//等到goroutine1注册完后再注册goroutine2
		<-order
		c2 := make(chan os.Signal, 1)
		signal.Notify(c2, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
		fmt.Printf("goroutine 2 receive a signal : %v\n\n", <-c2)
		wg.Done()
	}()

	wg.Wait()
	fmt.Printf("all groutine done!\n")
}

相同的代码,多次运行结果如下:
在这里插入图片描述
得出结论
捕捉信号的顺序和信号注册的顺序无关!

扩展

这里注册的三个信号的对应值。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值