Golang语言社区投稿golang高并发基于协程,通道的任务池

Posted Golang语言社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang语言社区投稿golang高并发基于协程,通道的任务池相关的知识,希望对你有一定的参考价值。

要点:
封装了协程模型基于select模型的通道传递;
支持同步和异步添加任务;由于golang无函数指针,任务函数利用了go 反射机制支持可变参的入参
开发者可以在高处理性能前提下,只专注业务开发,往任务池添加任务即可。

实例:
//taskpool.go 
package taskpool

import (
    "reflect"
    "time"
)

type Task struct {
    M_func interface{}
    M_args []interface{}
}

func (task *Task) Run() {
    go func() {
        f := reflect.ValueOf(task.M_func)
        if len(task.M_args) != f.Type().NumIn() {
            return
        }
        in := make([]reflect.Value, len(task.M_args))
        for k, param := range task.M_args {
            in[k] = reflect.ValueOf(param)
        }
        f.Call(in)

    }()
}

type WorkPool struct {
    TaskChannel chan Task
    QuitChan    chan int //终止通道
}

//size 设置缓存大
func (pool *WorkPool) InitPool(size int) {
    pool.TaskChannel = make(chan Task, size)
    pool.QuitChan = make(chan int)
    go func() {
    DONE:
        for {
            select {
            case task := <-pool.TaskChannel:
                task.Run()
            case <-pool.QuitChan:
                break DONE
            }
        }
    }()
}
func (pool *WorkPool) ClosePool() {
    pool.QuitChan <- 1
}

//同步阻塞方式添加任务
func (pool *WorkPool) AddTask(task Task) {
    pool.TaskChannel <- task
}

//非阻塞方式添加任务 time 超时时间 单位毫秒
func (pool *WorkPool) AddTaskSync(task Task, millitime int) bool {
    res := false
    go func(res bool) {
        select {
        case pool.TaskChannel <- task:
            res = true
        case <-time.After(time.Millisecond * time.Duration(millitime)):
            res = false
        }
    }(res)
    return res
}

//test_main.go
package main

import (
    "fmt"
    "ms_lib/ms_taskpool"
    "time"
)

func test(i int, test string) {
    fmt.Println("hahaha", i, test)
}

func main() {
    task_pool := ms_taskpool.WorkPool{}
    task_pool.InitPool(5)
    for i := 0; i < 1000; i++ {
        task := ms_taskpool.Task{M_func: test}
        task.M_args = append(task.M_args, i)
        task.M_args = append(task.M_args, "test")
        task_pool.AddTask(task)
    }
    //task_pool.ClosePool() //可强制主动关闭任务池

    time.Sleep(5 * time.Second)
    fmt.Println("test done!")
}


以上是关于Golang语言社区投稿golang高并发基于协程,通道的任务池的主要内容,如果未能解决你的问题,请参考以下文章

Golang✔️走进 Go 语言✔️ 第十六课 协程 & 通道

Golang✔️走进 Go 语言✔️ 第十六课 协程 & 通道

GoLang之协程

Golang协程并发的流水线模型

Go语言实现高并发日志监控系统

Go语言自学系列 | golang并发编程之协程