实现go并发的三种方式

复制代码
package main

import (
    "fmt"
    "sync"
    "time"
)

// 方法一: 通过sync.WaitGroup + chan自定义

var tokens chan struct{}
var wg sync.WaitGroup

func fprint(num int) {

    defer wg.Done()
    time.Sleep(10 * time.Microsecond)
    <-tokens

    fmt.Println(num)

}

func main() {
    t1 := time.Now()
    tokens = make(chan struct{}, 500) // 并发数量

    for num := 0; num < 100000; num++ {

        fmt.Printf("插入一个%d\n", num)
        wg.Add(1)
        tokens <- struct{}{}
        // fmt.Printf("队列长度----%d\n", len(tokens))
        go fprint(num)

    }
    wg.Wait()
    t := time.Since(t1)
    fmt.Println(t)

}
复制代码

 

复制代码
package main

import (
    "fmt"
    "sync"

    "time"

    "github.com/panjf2000/ants/v2"
)

func myFunc(num int32) {
    time.Sleep(10 * time.Microsecond)

    fmt.Println(num)
}

func demoFunc(num int32) {
    time.Sleep(10 * time.Microsecond)

    fmt.Println(num)
}

func main() {
    t1 := time.Now()
    defer ants.Release()

    runTimes := 100000
    var wg sync.WaitGroup

    //方法二:使用ants默认数量的goroutinues,打开源码可以看到链接池的容量大小为: math.MaxInt32*(2147483647)
    // Use the common pool.
    syncCalculateSum := func(num int32) func() {
        return func() {
            demoFunc(num)
            fmt.Printf("running goroutines: %d\n", ants.Running())
            wg.Done()
        }

    }
    for i := 0; i < runTimes; i++ {
        wg.Add(1)
        _ = ants.Submit(syncCalculateSum(int32(i))) //ants.Submit只接收func类型的参数
    }
    wg.Wait()
    // fmt.Printf("running goroutines: %d\n", ants.Running())
    fmt.Printf("finish all tasks.\n")

    //方法三:使用自定义数量的goroutinues
    // Use the pool with a function,
    // set 475 to the capacity of goroutine pool and 1 second for expired duration.
    p, _ := ants.NewPoolWithFunc(475, func(i interface{}) { // 并发数量475
        myFunc(i.(int32)) //业务函数
        wg.Done()
    }, ants.WithPreAlloc(true))
    defer p.Release()
    // Submit tasks one by one.
    for i := 0; i < runTimes; i++ {
        wg.Add(1)
        fmt.Printf("running goroutines: %d\n", p.Running())
        _ = p.Invoke(int32(i)) // 传递业务函数的参数
    }
    wg.Wait()

    fmt.Printf("finish all tasks\n")

    t := time.Since(t1)
    fmt.Println(t)
}
复制代码

 

posted @   明天OoO你好  阅读(513)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
历史上的今天:
2019-05-16 git当前项目免密提交
2019-05-16 git将代码提交到多个远程仓库
点击右上角即可分享
微信分享提示