golang优雅退出(进阶)

本文介绍了一种改进的Go程序优雅退出策略,确保在接收到退出信号后,任务通道中的所有数据都能得到处理,避免直接退出导致的数据丢失。通过四个步骤详细讲解了如何实现这一策略,包括停止写入数据、协程跳出循环、处理剩余数据和最终退出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前写过一篇程序优雅退出的文章
优雅退出:https://blog.youkuaiyun.com/qq_34673519/article/details/100128562

但是该策略存在一个问题,就是当任务通道中的信号没有被处理完时,收到退出信号后,通道中的数据同样不会被执行,直接退出。

package main

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


var wg sync.WaitGroup
var in=make(chan int,10)
var quit=make(chan int,1)
var quito0k=make(chan int,1)

func ListenQuit(){
	defer wg.Done()
	var sign=make(chan os.Signal,1)
	signal.Notify(sign,syscall.SIGINT)
	<-sign
	SQuit()

}

func run(){
	defer wg.Done()
Quit:
	for {
		select {
		case out := <-in:
			fmt.Println(out)
		case <-quit:
			time.Sleep(time.Second*1)
			break Quit
		}
	}

if len(in)>0 {//处理完通道中数据
	for i:=0;i<len(in);i++{
		<-in
		fmt.Println("11111")
	}
}

}

func producerin(){
Quit:
	for {
		select {
		case in<-0:
		case <-quit://停止写数据
			break Quit
		}
	}

}


func SQuit(){
	close(quit)
	go func(){
		wg.Wait()
		quito0k<-0
	}()
}
func main(){
	go ListenQuit()
	go func(){
		for i := 0; i <10; i++ {
			wg.Add(1)
			go run()
		}
	}()
	wg.Add(1)
	go producerin()
	<-quito0k
	fmt.Println("qiut ok")

}

第一步:
停止往通道中写数据

func producerin(){
Quit:
	for {
		select {
		case in<-0:
		case <-quit://停止写数据
			break Quit
		}
	}

}

第二步:
协程跳出for循环

for {
		select {
		case out := <-in:
			fmt.Println(out)
		case <-quit:
			time.Sleep(time.Second*1)
			break Quit
		}
	}

第三步:
处理通道中数据

if len(in)>0 {//处理完通道中数据
	for i:=0;i<len(in);i++{
		<-in
		fmt.Println("11111")
	}
}

第四步:退出
执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值