You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言竞态条件处理:如何确保main与attack耗时均正常输出?

Go协程竞态问题解决:确保defer函数执行并打印耗时(通道实现)

问题核心是:main函数读取到attack发送的通道值后立即退出,导致attack的defer timer函数还没来得及执行程序就终止了——Go程序会在main函数退出时立刻终止所有运行中的协程,不管协程有没有执行完。

以下是用通道实现的解决方案,确保main与attack的耗时都能稳定打印:

方案一:单个通道等待协程完全结束

修改逻辑,让attack的defer函数先打印耗时,再向通道发送信号,保证main只有在attack所有逻辑(包括defer)执行完才会退出:

package main

import (
    "fmt"
    "time"
)

func timer(funcName string) func() {
    startTime := time.Now()
    return func() {
        fmt.Printf("%s took %v time to run \n", funcName, time.Since(startTime))
    }
}

func main() {
    defer timer("main")()
    done := make(chan bool)
    evilNinja := "Tommy"
    go attack(evilNinja, done)
    <-done // 等待attack完全执行完毕(包括defer)
}

func attack(target string, done chan<- bool) {
    defer func() {
        timer("attack")() // 先打印耗时
        done <- true      // 再通知main可以退出
    }()
    time.Sleep(time.Second)
    fmt.Println("Throwing ninja stars at ", target)
}

方案二:保留攻击通知+新增协程结束通知

如果需要保留原有的“攻击完成”信号(比如要在main中处理后续逻辑),可以新增一个done通道,让main先处理攻击完成的逻辑,再等待协程完全结束:

package main

import (
    "fmt"
    "time"
)

func timer(funcName string) func() {
    startTime := time.Now()
    return func() {
        fmt.Printf("%s took %v time to run \n", funcName, time.Since(startTime))
    }
}

func main() {
    defer timer("main")()
    smokeSignal := make(chan bool)
    done := make(chan bool)
    evilNinja := "Tommy"
    go attack(evilNinja, smokeSignal, done)
    
    fmt.Println("Attack completed:", <-smokeSignal) // 处理攻击完成逻辑
    <-done // 等待attack的defer执行完毕
}

func attack(target string, smokeSignal chan<- bool, done chan<- bool) {
    defer func() {
        timer("attack")()
        done <- true
    }()
    time.Sleep(time.Second)
    fmt.Println("Throwing ninja stars at ", target)
    smokeSignal <- true // 通知攻击完成
}

方案原理

两种方案的核心都是让main函数等待attack协程的defer函数执行完毕。通过在defer代码块中发送通道信号,保证只有当attack的耗时打印完成后,main才会收到信号并退出程序,彻底消除了竞态条件。

内容的提问来源于stack exchange,提问作者Pruthviraj hawale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:33:22