【go每日一题】:并发任务调度器

news/2024/12/24 1:55:01 标签: golang, 开发语言, 后端

问题描述

需要实现一个并发的任务调度器,能够处理多个并发任务并限制同时执行的任务数量。
每个任务是一个函数,任务执行可能需要一段时间。
调度器的目的是控制同时执行的任务数量(即并发度),以防止任务数过多导致系统资源过载。

代码

package test

import (
	"fmt"
	"math/rand"
	"sync"
	"testing"
	"time"
	"trpc.group/trpc-go/trpc-go/log"
)

/**
你需要实现一个并发的任务调度器,能够处理多个并发任务并限制同时执行的任务数量。
每个任务是一个函数,任务执行可能需要一段时间。
调度器的目的是控制同时执行的任务数量(即并发度),以防止任务数过多导致系统资源过载。
*/

type TaskDispatcher struct {
	maxTask int
	c       chan func()
	wg      *sync.WaitGroup // 指针不进行初始化是nil
}

func NewTaskDispatcher(maxTaskNum int, chanCap int) *TaskDispatcher {
	return &TaskDispatcher{
		maxTask: maxTaskNum,
		c:       make(chan func(), chanCap),
		wg:      new(sync.WaitGroup),
	}
}

func (td *TaskDispatcher) AddNewTask(f func()) bool {
	select {
	case td.c <- f:
		td.wg.Add(1) // 这里加,消费完毕减少
		return true
	case <-time.After(3 * time.Second):
		return false
	}
}

func (td *TaskDispatcher) RunDispatcher() {
	for i := 0; i < td.maxTask; i++ {
		go func(i int) {
			for f := range td.c {
				log.Info(fmt.Sprintf("当前第%d个协程正在执行任务", i))

				if f != nil {
					f()
				}

				time.Sleep(time.Second * time.Duration(rand.Intn(3)+1))
				fmt.Println("当前函数执行完毕")
				td.wg.Done()
			}
		}(i)
	}
}

func (td *TaskDispatcher) StopDispatcher() {

	defer close(td.c)
	td.wg.Wait()
}

func TestTaskDispatcher(t *testing.T) {
	td := NewTaskDispatcher(3, 10)

	td.RunDispatcher() //channel先有接收方,才向channel中发数据

	for i := 0; i < 20; i++ {
		td.AddNewTask(func() {
			fmt.Printf("这里是任务%v\n", i)
		})
	}

	td.StopDispatcher()
}


http://www.niftyadmin.cn/n/5797211.html

相关文章

如何详细地遵循RustDesk的步骤来搭建远程访问和自定义服务器?

要详细地遵循RustDesk的步骤来搭建远程访问和自定义服务器&#xff0c;你可以按照以下几个主要步骤进行操作&#xff1a; 下载并安装RustDesk&#xff1a;前往RustDesk的官方网站&#xff08;https://rustdesk.com/&#xff09;下载适用于你的操作系统的安装程序。然后&#xf…

【Leecode】Leecode刷题之路第87天之扰乱字符串

题目出处 87-扰乱字符串-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 87-扰乱字符串-官方解法 方法1&#xff1a;动态规划 思路&#xff1a; 代码示例&#xff1a;&#xff08;Java&…

wordpress调用指定分类ID下 相同标签的内容

要在WordPress中调用分类ID为1、3、7的分类下&#xff0c;具有相同标签的前10个内容&#xff0c;可以使用自定义的WordPress查询(WP_Query)。以下是实现此功能的步骤和示例代码&#xff1a; 步骤&#xff1a; 确定共同标签&#xff1a; 首先&#xff0c;你需要确定分类1、3、…

泛型(2)

泛型&#xff08;2&#xff09; 1、泛型在继承上的体现 如果B是A的一个子类型&#xff08;子类或者子接口&#xff09;&#xff0c;而G是具有泛型声明的类或接口&#xff0c;G并不是G的子类型&#xff01; 比如&#xff1a;String是Object的子类&#xff0c;但是List并不是…

网络七层杀伤链

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&…

Linux SHELL脚本中的变量与运算

一.SHELL脚本中的变量 1.1.什么是变量 在编写程序时&#xff0c;通常会遇到被操作对象不固定的情况 我们需要用一串固定的字符来表示不固定的值这就是变量存在的根本意义 变量的实现原理就是内存存储单元的一个符号名称 1.2.变量的命名规则 变量的名称中只能包含数字、大…

QT_Demo(1)之实现多线程实现简单的电脑摄像头视频流开关

QT_Demo&#xff08;1&#xff09;之实现多线程实现简单的电脑摄像头视频流开关 使用qt中的多线程进行功能控制&#xff1a;继承QThread直接通过代码进行UI搭建简单示例使用信号与槽 1. 功能介绍 首先想搭一个界面可以交互&#xff0c;从而实现手动开关笔记本摄像头的目的 想…

C#经典算法面试题

网络上收集的一些C#经典算法面试题&#xff0c;分享给大家 # 递归算法 ## C#递归算法计算阶乘的方法 > 一个正整数的阶乘&#xff08;factorial&#xff09;是所有小于及等于该数的正整数的积&#xff0c;并且0的阶乘为1。自然数n的阶乘写作n!。1808年&#xff0c;基斯顿…