Go 语言中实现优雅的停止程序

时间:2025-03-30 11:32:24
/**
Go 语言中实现优雅的停止程序
主goroutine监听操作系统消息,收到系统停止消息后关闭server的chan,所有子协程检测到chan关闭,则全部退出
**/
package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

// An uninteresting service.
type Service struct {
	ch        chan bool
	waitGroup *
}

// Make a new Service.
func NewService() *Service {
	return &Service{
		ch:        make(chan bool),
		waitGroup: &{},
	}
}

// Accept connections and spawn a goroutine to serve each one.  Stop listening
// if anything is received on the service's channel.
func (s *Service) Serve(listener *) {
	(1)
	defer ()
	for {
		select {
		case <-:
			("stopping listening on", ())
			()
			return
		default:
		}
		(().Add(1e9))
		conn, err := ()
		if nil != err {
			//判断错误类型是否是
			if opErr, ok := err.(*); ok && () {
				continue
			}
			(err)
		}
		((), "connected")
		go (conn)
	}
}

// Stop the service by closing the service's channel.  Block until the service
// is really stopped.
func (s *Service) Stop() {
	close()
	()
}

// Serve a connection by reading and writing what was read.  That's right, this
// is an echo service.  Stop reading and writing if anything is received on the
// service's channel but only after writing what was read.
func (s *Service) serve(conn *) {
	defer ()
	(1)
	defer ()
	for {
		select {
		case <-:
			("disconnecting", ())
			return
		default:
		}
		(().Add(1e9))
		buf := make([]byte, 4096)
		if _, err := (buf); nil != err {
			if opErr, ok := err.(*); ok && () {
				continue
			}
			(err)
			return
		}
		if _, err := (buf); nil != err {
			(err)
			return
		}
	}
}

func main() {

	// Listen on 127.0.0.1:48879.  That's my favorite port number because in
	// hex 48879 is 0xBEEF.
	laddr, err := ("tcp", "127.0.0.1:48879")
	if nil != err {
		(err)
	}
	listener, err := ("tcp", laddr)
	if nil != err {
		(err)
	}
	("listening on", ())

	// Make a new service and send it into the background.
	service := NewService()
	go (listener)

	// Handle SIGINT and SIGTERM.
	ch := make(chan )
	(ch, , )
	("signal:", <-ch)

	// Stop the service gracefully.
	()

}