MST

星途 面试题库

面试题:Go并发编程中条件变量与互斥锁如何协同实现简单任务调度

请编写一段Go代码,利用条件变量和互斥锁实现一个简单的任务调度器。要求有一个主协程向任务队列中添加任务,另外有若干工作协程从任务队列中取出任务并执行。任务以函数形式表示,每次工作协程执行完一个任务后,等待主协程添加新任务再继续执行。
43.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "sync"
)

// Task 定义任务类型
type Task func()

// TaskScheduler 任务调度器
type TaskScheduler struct {
    tasks    chan Task
    wg       sync.WaitGroup
    mutex    sync.Mutex
    cond     *sync.Cond
    running  bool
}

// NewTaskScheduler 创建新的任务调度器
func NewTaskScheduler(numWorkers int) *TaskScheduler {
    ts := &TaskScheduler{
        tasks:   make(chan Task),
        running: true,
    }
    ts.cond = sync.NewCond(&ts.mutex)
    for i := 0; i < numWorkers; i++ {
        ts.wg.Add(1)
        go func() {
            defer ts.wg.Done()
            for {
                task, ok := <-ts.tasks
                if!ok {
                    return
                }
                task()
                ts.mutex.Lock()
                for!ts.running && len(ts.tasks) == 0 {
                    ts.cond.Wait()
                }
                if!ts.running {
                    break
                }
                ts.mutex.Unlock()
            }
        }()
    }
    return ts
}

// AddTask 添加任务到任务队列
func (ts *TaskScheduler) AddTask(task Task) {
    ts.mutex.Lock()
    ts.tasks <- task
    ts.cond.Broadcast()
    ts.mutex.Unlock()
}

// Stop 停止任务调度器
func (ts *TaskScheduler) Stop() {
    ts.mutex.Lock()
    ts.running = false
    close(ts.tasks)
    ts.cond.Broadcast()
    ts.mutex.Unlock()
    ts.wg.Wait()
}

func main() {
    scheduler := NewTaskScheduler(3)

    // 添加任务
    scheduler.AddTask(func() {
        fmt.Println("Task 1 is running")
    })
    scheduler.AddTask(func() {
        fmt.Println("Task 2 is running")
    })

    // 停止调度器
    scheduler.Stop()
}