MST

星途 面试题库

面试题:Go调度器中如何简单实现任务优先级

在Go调度器的基础上,假设我们有一些不同优先级的任务,简述如何通过代码简单实现让高优先级任务优先执行。请描述关键的数据结构和调度逻辑思路。
19.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

关键数据结构

  1. 任务结构体
type Task struct {
    ID       int
    Priority int
    // 其他任务相关数据
    Func func()
}
  1. 优先级队列:用于存储任务,可使用堆(heap)数据结构实现。Go标准库中的container/heap包可帮助实现堆。
type PriorityQueue []*Task

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
    // 高优先级在前
    return pq[i].Priority > pq[j].Priority
}

func (pq PriorityQueue) Swap(i, j int) {
    pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
    *pq = append(*pq, x.(*Task))
}

func (pq *PriorityQueue) Pop() interface{} {
    old := *pq
    n := len(old)
    item := old[n - 1]
    *pq = old[0 : n - 1]
    return item
}

调度逻辑思路

  1. 任务入队:当有新任务生成时,将任务根据其优先级插入到优先级队列中。
func EnqueueTask(task *Task, pq *PriorityQueue) {
    heap.Init(pq)
    heap.Push(pq, task)
}
  1. 任务出队执行:调度器从优先级队列中取出优先级最高的任务(堆顶元素),并执行该任务的函数。
func DequeueAndExecute(pq *PriorityQueue) {
    heap.Init(pq)
    for pq.Len() > 0 {
        task := heap.Pop(pq).(*Task)
        task.Func()
    }
}
  1. 结合Go调度器:在Go调度器的基础上,可以创建一个或多个goroutine来执行任务出队和执行的操作。例如:
func main() {
    var pq PriorityQueue
    // 模拟添加任务
    task1 := &Task{ID: 1, Priority: 5, Func: func() { println("Task 1 executed") }}
    task2 := &Task{ID: 2, Priority: 3, Func: func() { println("Task 2 executed") }}
    EnqueueTask(task1, &pq)
    EnqueueTask(task2, &pq)

    go DequeueAndExecute(&pq)

    // 防止主程序退出
    select {}
}

在实际应用中,可能还需要考虑任务阻塞、资源限制等更多因素,确保高优先级任务在合适的时机能够真正优先执行。