package main
import (
"context"
"fmt"
"runtime"
"strconv"
"time"
"github.com/silentred/gid"
//"log"
"os"
"os/signal"
"syscall"
)
//RegisterSignalHandler 注册信号处理
func RegisterSignalHandler() chan os.Signal {
runtime.GOMAXPROCS(runtime.NumCPU())
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP)
// signal.Notify(c, os.Interrupt, os.Kill)
// s := <-c
// fmt.Println("Got signal:", s)
return c
}
//SignalHandler 信号处理句柄
func SignalHandler(c chan os.Signal, cancel context.CancelFunc) {
//Got signal获取信号
signalChan := <-c
for {
switch signalChan {
case syscall.SIGQUIT:
fmt.Printf("SIGQUIT [#%d] ", gid.Get())
signal.Stop(c)
cancel()
os.Exit(5)
break
case syscall.SIGTERM: //kill 进程
fmt.Printf("SIGTERM [#%d] ", gid.Get())
signal.Stop(c)
cancel()
os.Exit(6)
break
case syscall.SIGSTOP:
fmt.Printf("SIGSTOP [#%d] ", gid.Get())
signal.Stop(c)
cancel()
os.Exit(2)
case syscall.SIGINT: //ctrl+c
fmt.Println("SIGINT syscall.SIGINT")
signal.Stop(c)
cancel()
time.Sleep(3 * time.Second)
os.Exit(1)
case syscall.SIGHUP:
fmt.Printf("SIGHUP [#%d] ", gid.Get())
cancel()
os.Exit(3)
default:
fmt.Printf("default [#%d] ", gid.Get())
}
}
}
func doMyRuntime(ctx context.Context, routineIndex int) {
fmt.Println("协程持续执行")
desc := "-------子协程"
var i int
fmt.Printf("main goroutine [#%d] ", gid.Get(), desc)
for {
select {
case <-ctx.Done(): //此处实现子协程退出,直接退出 for循环
fmt.Println("第" + strconv.Itoa(routineIndex) + "号" + "调用处主动取消了" + strconv.Itoa(routineIndex))
return
default:
//TODO 此处调用实现并行处理数据的逻辑
time.Sleep(1 * time.Second)
fmt.Println(desc+"第"+strconv.Itoa(routineIndex)+"号", i)
i++
}
}
}
func main() {
routimeNum := 2
ctx := SystemSignalDeal()
for index := 0; index < routimeNum; index++ {
go doMyRuntime(ctx, index)
}
doNowRoutimeAction(ctx, "主协程")
}
//SystemSignalDeal 系统信号收集并和处理
func SystemSignalDeal() context.Context {
sc := RegisterSignalHandler()
ctx, cancel := context.WithCancel(context.Background())
go SignalHandler(sc, cancel)
return ctx
}
//主协程只为做状态记录和子协程状态控制用。类似swoole的master进程
func doNowRoutimeAction(ctx context.Context, desc string) {
var i int
fmt.Printf("main goroutine [#%d] ", gid.Get(), desc)
time.Sleep(1 * time.Second)
fmt.Println(desc, i)
i++
}