首頁  >  文章  >  後端開發  >  運行中的競賽條件

運行中的競賽條件

王林
王林轉載
2024-02-08 21:00:041176瀏覽

運行中的競賽條件

問題內容

當程式碼運行時,有時會列印attack()函數所花費的時間 我知道當攻擊寫入通道並且主要讀取它然後主要退出並且不等待計時器(“攻擊”)執行時,它們是競爭條件

我是新來的:_)

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)
    evilNinga := "Tommy"
    go attack(evilNinga, smokeSignal)
    fmt.Println(<-smokeSignal)
}

func attack(target string, smokeSignal chan<-bool){
    defer timer("attack")()
    time.Sleep(time.Second)
    fmt.Println("Throwing ninja stars at ", target)
    smokeSignal <- true
}

有人可以告訴我如何處理這種情況,我想列印兩個函數所花費的時間,並使用通道


#正確答案


main 退出時,程式將終止,並發goroutine 不會正常終止(在許多程式中,非主goroutine 是輔助“守護程式”,根本不會關閉),因此不能保證現有的defer 會運作。這就是這裡發生的情況:當您發送煙霧信號時,如果 attack goroutine 被取消調度,那麼 main 可以在重新調度之前返回,因此 defer 永遠不會運行。

有很多選項可以處理這個問題,但所有這些都會導致基本上相同的結果:確保在函數運行後在通道上發送,您可以透過for 來做到這一點實例(非詳盡)

  • 推遲在計時器之前發送訊息(推遲以相反的順序運行)
  • 子函數中的 defer(),外部函數中的 signal
  • 不要使用 defer,只需在發送訊號之前執行退出訊息
  • 不要單獨發送訊息和列印,而是透過通道發送函數的運行時間,並讓呼叫者格式化並報告

以上是運行中的競賽條件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除