场景1:实现并发调用多个方法,有一个返回结果就都返回
思路:可以使用 select 语句结合通道来等待多个 goroutine 返回结果,一旦有 goroutine 返回结果,就立即处理该结果并结束程序。

/**
 * @desc
 * @date 2025/4/19
 * @user yangshuo
 */

package main

import (
    "fmt"
    "time"
)

func https(resultChan chan string) {
    // 模拟 HTTP 请求
    // t := time.NewTicker(time.Duration(rand.Intn(5)+1) * time.Second)

    time.Sleep(time.Duration(4+1) * time.Second)
    resultChan <- "http"
    println("1")
}

func redis(resultChan chan string) {
    // 模拟 HTTP 请求
    // t := time.NewTicker(time.Duration(rand.Intn(5)+1) * time.Second)
    // <-t.C
    time.Sleep(time.Duration(5+1) * time.Second)
    resultChan <- "redis"
    println("2")
}

func mysql(resultChan chan string) {
    // 模拟 HTTP 请求
    // t := time.NewTicker(time.Duration(rand.Intn(5)+1) * time.Second)
    // <-t.C
    time.Sleep(time.Duration(3+1) * time.Second)
    resultChan <- "mysql"
    println("3")
}

func main() {
    resultChan := make(chan string)
    defer close(resultChan)

    go https(resultChan)
    go mysql(resultChan)
    go redis(resultChan)

    for {
        select {
        case result := <-resultChan:
            fmt.Println("返回结果:", result)
            return
        }
    }

}

场景2:实现并发调用多个校验方法,有一个成功就返回成功,所有方法都失败就返回失败。
思路:与场景1不同的是,失败情况需要等待所有goroutine都执行完。

/**
 * @desc
 * @date 2025/4/20
 * @user yangshuo
 */

package main

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

func validateFunc1() bool {
    // 模拟验证逻辑
    // 设置随机种子
    return false
    rand.Seed(time.Now().UnixNano())

    // 生成随机数(0 或 1)
    randomNum := rand.Intn(2)

    // 根据随机数返回 true 或 false
    result := randomNum == 1
    fmt.Println(result)
    return result
}

func validateFunc2() bool {
    return false
    // 设置随机种子
    rand.Seed(time.Now().UnixNano())

    // 生成随机数(0 或 1)
    randomNum := rand.Intn(2)

    // 根据随机数返回 true 或 false
    result := randomNum == 1
    fmt.Println(result)
    return result
}

func validateFunc3() bool {
    return false
    // 模拟验证逻辑
    // 设置随机种子
    rand.Seed(time.Now().UnixNano())

    // 生成随机数(0 或 1)
    randomNum := rand.Intn(2)

    // 根据随机数返回 true 或 false
    result := randomNum == 1
    fmt.Println(result)
    return result
}

func main() {
    // 定义验证函数
    validateFuncs := []func() bool{validateFunc1, validateFunc2, validateFunc3}
    // 使用 channel 通知是否有函数通过验证
    passed := make(chan bool)

    // 并发调用验证函数
    for _, vf := range validateFuncs {
        go func(fn func() bool) {
            if fn() {
                passed <- true
            }
        }(vf)
    }

    // 检查是否有函数通过验证
    for range validateFuncs {
        select {
        case <-passed:
            fmt.Println("Validation passed")
            return
    }

    fmt.Println("Validation failed")
}

需要注意的是:当所有 goroutines 都未通过验证时,由于没有 goroutine 向 passed 通道发送消息,select 语句会一直阻塞等待消息,从而导致程序发生死锁。为了避免这种情况,可以加上default分支。

// 检查是否有函数通过验证
    for range validateFuncs {
        select {
        case <-passed:
            fmt.Println("Validation passed")
            return
        default:

        }
    }

标签: none

添加新评论

  • 上一篇: 1
  • 下一篇: 没有了