首页 > 编写go语言协程池遇到的问题

编写go语言协程池遇到的问题

初学go语言,尝试使用go协程池完成一项高并发任务。代码中有一个协程每隔0.00125秒向任务队列中添加一个任务(理论上每秒能向工作队列添加800个协程),每隔任务执行的时间为0.22秒。协程池中协程的数量为400,理论上协程池1秒能够完成800个任务(1/0.00125),然而实际执行10秒后发现仅有700个任务被执行,理论上10秒应该有8000个任务被协程池执行。为此我打印了所有被添加的任务id,发现10秒内仅仅添加了700个任务。为此我取消了添加任务的时间间隔(注释了time.Sleep(1250 * time.Microsecond)这行代码),此时发现10秒内共向任务队列添加了27000个任务,同时协程池在10秒内共完成了17000个任务,比较接近理论数值,这是什么原因导致的呢?


package main
 
import (
    "fmt"
    "sync"
    "time"
)
 
type Task interface {
    Execute()
}
 
type PrintTask struct {
    taskID  int
    message string
}
 
func (p PrintTask) Execute() {
    fmt.Printf("Task %d: %s\n", p.taskID, p.message)
    time.Sleep(220 * time.Millisecond)
}
 
func worker(id int, jobs <-chan Task, wg *sync.WaitGroup) {
    defer wg.Done()
    for task := range jobs {
        fmt.Println("worker", id, "started job")
        task.Execute() // 异步执行任务
        // go task.Execute() // 异步执行任务
    }
}
 
func main() {
    jobs := make(chan Task, 10000)
    var wgWorkers sync.WaitGroup
 
    // 启动400个工作协程
    for w := 1; w <= 400; w++ {
        wgWorkers.Add(1)
        go worker(w, jobs, &wgWorkers)
    }
 
    // 异步添加任务
    go func() {
        taskID := 0
        for {
            select {
            case jobs <- PrintTask{taskID, "Hello, World!"}:
                taskID++
                fmt.Println("添加的任务id是",taskID)
                // time.Sleep(1250 * time.Microsecond)
            default:
                // 当任务队列已满时,等待一段时间再尝试添加任务
                time.Sleep(100 * time.Millisecond)
                fmt.Println("工作队列已满")
            }
        }
    }()
 
    // 模拟运行一段时间后停止添加任务
 
    time.Sleep(10 * time.Second)
    close(jobs) // 关闭任务队列
 
    wgWorkers.Wait() // 等待所有工作协程完成
}

全部评论

(5) 回帖
加载中...
话题 回帖

近期热帖

近期精华帖

热门推荐