MST

星途 面试题库

面试题:Go语言并发任务调度系统中的资源限制

假设在Go语言的并发任务调度系统中,有CPU和内存的资源限制。例如,同时运行的任务不能超过10个(CPU限制),并且所有运行任务占用的总内存不能超过1GB(内存限制)。请设计并实现一个机制,能够在任务调度过程中动态监控和控制这些资源,确保系统不会因为资源耗尽而崩溃。阐述设计思路并给出关键代码片段。
20.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 任务结构体:定义一个任务结构体,包含任务执行函数、任务ID以及任务所需内存大小等信息。
  2. 资源监控:使用两个计数器,一个用于记录当前运行的任务数量(CPU限制),另一个用于记录当前所有运行任务占用的总内存。
  3. 任务调度:使用一个任务队列来存储等待执行的任务。当有新任务提交时,先检查是否满足资源限制条件。如果满足,则将任务从队列中取出并执行;如果不满足,则任务留在队列中等待。
  4. 资源释放:当任务执行完成后,需要及时释放其所占用的资源,更新计数器。

关键代码片段

package main

import (
    "fmt"
    "sync"
)

// 定义任务结构体
type Task struct {
    ID     int
    Memory int // 任务所需内存大小,单位为MB
    Run    func()
}

// 定义资源限制
const (
    MaxTasks    = 10
    MaxMemoryMB = 1024
)

// 全局变量
var (
    taskQueue  []Task
    running    int
    totalMem   int
    mutex      sync.Mutex
    wg         sync.WaitGroup
)

// 提交任务
func SubmitTask(task Task) {
    mutex.Lock()
    taskQueue = append(taskQueue, task)
    mutex.Unlock()
    schedule()
}

// 调度任务
func schedule() {
    mutex.Lock()
    for running < MaxTasks && totalMem < MaxMemoryMB && len(taskQueue) > 0 {
        task := taskQueue[0]
        taskQueue = taskQueue[1:]
        if totalMem+task.Memory <= MaxMemoryMB {
            running++
            totalMem += task.Memory
            mutex.Unlock()
            wg.Add(1)
            go func(t Task) {
                defer wg.Done()
                t.Run()
                mutex.Lock()
                running--
                totalMem -= t.Memory
                schedule()
                mutex.Unlock()
            }(task)
        } else {
            mutex.Unlock()
            break
        }
    }
    mutex.Unlock()
}

func main() {
    // 示例任务
    task1 := Task{
        ID:     1,
        Memory: 100,
        Run: func() {
            fmt.Println("Task 1 is running")
        },
    }
    task2 := Task{
        ID:     2,
        Memory: 200,
        Run: func() {
            fmt.Println("Task 2 is running")
        },
    }
    SubmitTask(task1)
    SubmitTask(task2)
    wg.Wait()
}