ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GO协程管理

2022-05-04 18:35:26  阅读:155  来源: 互联网

标签:协程 func 管理 GLimit 信号 context GO runtime


协程管理

goroutine的管理

  • runtime.GOMAXPROCS(2) 分配2个逻辑处理器给调度器使用

  • runtime.Gosched() 当前goroutine从当前线程退出,并放回到队列

  • runtime.NumGoroutine() 查看当前存在的协程数

  • 通过带缓冲的channel可以实现对goroutine数量的控制

    • 控制协程数量代码:

      package main
      
      import (
      	"fmt"
      	"runtime"
      	"time"
      )
      
      type GLimit struct {
      	Limit int
      	ch    chan struct{}
      }
      
      func NewGLimit(limit int) *GLimit {
      	return &GLimit{
      		Limit: limit,
      		ch:    make(chan struct{}, limit),
      	}
      }
      
      func (glimit *GLimit) Run(foo func()) {
      	glimit.ch <- struct{}{}
      	go func() {
      		foo()
      		<-glimit.ch
      	}()
      }
      
      func add() {
      	time.Sleep(100 * time.Millisecond)
      	_ = 4
      }
      
      func main() {
      	ticker := time.NewTicker(1 * time.Second)
      	defer ticker.Stop()
      	go func() {
      		for {
      			<-ticker.C
      			fmt.Printf("go routine number %d\n", runtime.NumGoroutine())
      		}
      	}()
      	gl := NewGLimit(100)
      	for {
      		gl.Run(add)
      	}
      }
      

优雅地退出守护协程

  • 守护协程:独立于控制终端和用户请求的协程,它一直存在,周期性执行某种任务或等待处理某些发生的事件。伴随着main协程的退出,守护协程也退出。
  • kill命令不是杀死进程,它只是向进程发送信号kill -s pid,s的默认值是15.常见的终止信号如下:
信号 说明
SIGINT 2 Ctrl+C触发
SIGKILL 9 无条件结束程序,不能捕获、阻塞或忽略
SIGTERM 15 结束程序,可以捕获、阻塞或忽略
  • 监听信号示例代码
package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"
)

var ctx context.Context
var cancle context.CancelFunc

func init() {
	ctx, cancle = context.WithCancel(context.Background())
}

// 监听一个信号
func listenSignal() {
	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case sig := <-c:
			fmt.Printf("receive signal %d\n", sig)
			cancle()
			return
		}
	}
}

// 监听前端请求
func listenHttp(port int) {
	server := &http.Server{Addr: ":" + strconv.Itoa(port), Handler: nil}
	go func() {
		for {
			select {
			case <-ctx.Done():
				server.Close()
				return
			}
		}
	}()
	server.ListenAndServe()
	fmt.Printf("stop listen http request on port %d\n", port)
}

func main() {
	go listenHttp(8080)
	go listenHttp(8081)
	go listenSignal()
	time.Sleep(10 * time.Second)
}

协程管理组件

  • go get github.com/x-mod/routine
  • 封装了常规的业务逻辑:初始化、收尾清理、工作协程、守护协程、监听term信号
  • 封装了常见的协程组织形式:并行、串行、定时任务、超时控制、重试、profiling

标签:协程,func,管理,GLimit,信号,context,GO,runtime
来源: https://www.cnblogs.com/Otiger/p/16221865.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有