go语言之异步并发

1.首先讲一下 匿名函数和闭包的概念,(仔细看,其实Python代码里很好看,只不过Go语言代码有点多,看起来很复杂的感觉)

package main

import "fmt"

func main() {
    /*注意:匿名函数和闭包往往是一起出现的*/
    //不带参的匿名函数
    func() {
        fmt.Printf("不带参数的匿名函数;\n")
    }()

    //带参数的匿名函数
    func(key string) {
        fmt.Printf("带参数的匿名函数:%s;\n", key)
    }("666")

    //不常用的调用方式,但是方便理解
    //声明函数变量
    Fun1 := func(name string, age int) {
        fmt.Printf("我叫%s,今年%d;\n", name, age)
    }
    //调用函数
    Fun1("霍雨浩", 15)

}
/*
不带参数的匿名函数;
带参数的匿名函数:666;
我叫霍雨浩,今年15;

*/

2.并发

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func OneFun(key string, wg *sync.WaitGroup, mutex *sync.Mutex, resDict map[string]string) {
    defer wg.Done()

    tempTime := rand.Intn(10) + 1
    fmt.Printf("key:%s,tempTime:%d\n", key, tempTime)
    time.Sleep(time.Duration(tempTime) * time.Second)

    // 锁住
    mutex.Lock()
    resDict[key] = "成功"
    mutex.Unlock()

}

func SyncDoFun() map[string]string {
    // 定义返回值
    resDict := make(map[string]string)
    wg := sync.WaitGroup{}
    mutex := sync.Mutex{}
    for _, key := range []string{"A", "B", "C", "D"} {
        wg.Add(1)
        // 匿名函数+闭包,最好带参数,因为里面要用
        go func(key string, wg *sync.WaitGroup, mutex *sync.Mutex, resDict map[string]string) {
            OneFun(key, wg, mutex, resDict)
        }(key, &wg, &mutex, resDict)
    }

    wg.Wait()
    return resDict
}

func main() {
    resDict := SyncDoFun()
    fmt.Println(resDict)
}
/*
key:A,tempTime:5
key:D,tempTime:5
key:C,tempTime:9
key:B,tempTime:8
map[A:成功 B:成功 C:成功 D:成功]
*/

 3.0升级版

package main

import (
    "fmt"
    "sync"
)

// 保持DemoFun不变,因为它是一个简单的示例函数
func DemoFun() string {
    return "成功"
}

// 定义DemoFun1为函数类型,但重命名为TaskFunc以更清楚地表示其用途
type TaskFunc func() string

// 将SyncOneFun重命名为executeTask,以更清晰地表达其目的
func executeTask(key string, wg *sync.WaitGroup, mutex *sync.Mutex, resultMap map[string]string, task TaskFunc) {
    defer wg.Done()

    mutex.Lock()
    resultMap[key] = task()
    mutex.Unlock()
}

// 将SyncDemoFun重命名为runParallelTasks,以更清晰地表达其执行多个任务的目的
func runParallelTasks(keyList []string, task TaskFunc) map[string]string {
    wg := &sync.WaitGroup{}
    mu := &sync.Mutex{}

    resultMap := make(map[string]string)

    for _, key := range keyList {
        wg.Add(1)

        go func(key string, wg *sync.WaitGroup, mutex *sync.Mutex, resultMap map[string]string, task TaskFunc) {
            executeTask(key, wg, mutex, resultMap, task)
        }(key, wg, mu, resultMap, task)
    }
    wg.Wait()
    return resultMap
}

func main() {
    fmt.Println("Hello World")
    keyList := []string{"A", "B", "C"}
    resultMap := runParallelTasks(keyList, DemoFun)
    fmt.Println(resultMap)
}

 4.0

package main

import (
    "fmt"
    "sync"
)

func DemoFun() string {
    return "成功"
}

type TaskFunc func() string

func runParallelTasks(keyList []string, task TaskFunc) map[string]string {
    wg := &sync.WaitGroup{}
    mu := &sync.Mutex{}
    resultMap := make(map[string]string)

    for _, key := range keyList {
        wg.Add(1)

        // 使用闭包来捕获key和task的当前值
        go func(key string) {
            defer wg.Done()
            mu.Lock()
            resultMap[key] = task()
            mu.Unlock()
        }(key)
    }

    wg.Wait()
    return resultMap
}

func main() {
    fmt.Println("Hello World")
    keyList := []string{"A", "B", "C"}
    resultMap := runParallelTasks(keyList, DemoFun)
    fmt.Println(resultMap)
}

 

posted @ 2024-06-17 11:10    阅读(2)  评论(0编辑  收藏  举报