MST

星途 面试题库

面试题:Go语言中并发编程时,如何在多个goroutine间合理分配CPU资源

在Go并发编程场景下,假设你有多个需要执行的任务在不同的goroutine中,这些任务对CPU资源需求不同,阐述你会采用哪些方式来确保这些goroutine能合理分配到CPU资源,举例说明相关方法的使用。
32.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 使用runtime.GOMAXPROCS设置CPU核心数
    • 可以通过runtime.GOMAXPROCS函数来设置Go程序能够使用的CPU核心数。这能控制整个程序可以并行执行的最大goroutine数量。
    • 示例代码:
package main

import (
    "fmt"
    "runtime"
)

func main() {
    // 设置使用2个CPU核心
    runtime.GOMAXPROCS(2)
    var numTasks = 10
    for i := 0; i < numTasks; i++ {
        go func(taskID int) {
            // 模拟不同的CPU需求任务
            for j := 0; j < 1000000000; j++ {
                if taskID%2 == 0 {
                    // 对CPU需求高的任务
                    _ = j * j
                } else {
                    // 对CPU需求相对低的任务
                    _ = j + j
                }
            }
            fmt.Printf("Task %d completed\n", taskID)
        }(i)
    }
    select {}
}
  1. 使用sync.WaitGroup控制任务同步
    • sync.WaitGroup用于等待一组goroutine完成。通过它可以确保所有任务都执行完毕后,程序才退出,避免程序提前结束导致部分任务未完成。
    • 示例代码:
package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    var numTasks = 10
    for i := 0; i < numTasks; i++ {
        wg.Add(1)
        go func(taskID int) {
            defer wg.Done()
            // 模拟不同的CPU需求任务
            for j := 0; j < 1000000000; j++ {
                if taskID%2 == 0 {
                    // 对CPU需求高的任务
                    _ = j * j
                } else {
                    // 对CPU需求相对低的任务
                    _ = j + j
                }
            }
            fmt.Printf("Task %d completed\n", taskID)
        }(i)
    }
    wg.Wait()
}
  1. 使用channel进行任务调度和资源控制
    • 可以创建一个channel,限制同时执行的任务数量,从而间接控制CPU资源。例如,创建一个容量为n的无缓冲channel,只有当channel中有空闲位置时,新的任务才能进入执行。
    • 示例代码:
package main

import (
    "fmt"
)

func main() {
    var numTasks = 10
    semaphore := make(chan struct{}, 2) // 同时最多执行2个任务
    for i := 0; i < numTasks; i++ {
        semaphore <- struct{}{}
        go func(taskID int) {
            defer func() { <-semaphore }()
            // 模拟不同的CPU需求任务
            for j := 0; j < 1000000000; j++ {
                if taskID%2 == 0 {
                    // 对CPU需求高的任务
                    _ = j * j
                } else {
                    // 对CPU需求相对低的任务
                    _ = j + j
                }
            }
            fmt.Printf("Task %d completed\n", taskID)
        }(i)
    }
    select {}
}