我的測驗代碼如下
type Data struct {
data int
}
func printData(c chan *Data) {
time.Sleep(time.Second * 1)
data := <-c
for {
data.data = 100
}
}
func main() {
fmt.Println("Main started...")
a := Data{data: 1}
b := &a
//create channel
c := make(chan *Data, 10)
go printData(c)
fmt.Println(fmt.Printf("Value of b before putting into channel %v", *b))
c <- b
for {
b.data = 20
}
}
我go build -race用來構建二進制檔案,正如預期的那樣發生資料競爭
我的疑問是我認為傳遞指標是不正確的,因為當使用帶有多個 goroutines 的通道時,通道有一個鎖,但是一個傳遞給通道的指標,導致 goroutines 需要添加另一個鎖來保護資料競爭。有點奇怪
所以我的理解是對的?
uj5u.com熱心網友回復:
因為兩個例程試圖在沒有同步的情況下使用同一個底層物件,所以您有資料競爭。如果您在創建 goroutine 之前存盤了一個指向共享物件的指標,那么您將在沒有通道的情況下獲得相同的競爭。你會不會有一個比賽中,如果,路過的指標后,你在這兩個夠程的一個停止使用的基本物件。因此,問題不是通道本身,而是在兩個單獨的 goroutine 中使用共享的底層物件。
該共享方法是不相關的,換句話說。有共享這一事實很重要。
CSP背后的一個想法是通過通信來共享(即發送需要處理的實際資料)而不是通過共享來通信(即說服兩個可能同時運行的獨立的順序處理器在共享資料時表現良好)。
當資料本身非常大時,發送一個指標——并立即“擺脫”底層資料——可能是一個很好的策略,以降低資料復制的成本。但這是一種優化技術,只有在性能分析表明資料復制是操作的昂貴部分之后才應該進行。添加指標間接增加了性能成本,這必須通過降低的通信成本來彌補。在您的特定情況下,要操作的資料由單個int值組成,因此增加的指標成本大大超過任何其他降低的成本,并且您應該只在演算法需要時共享資料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/393699.html
標籤:去
下一篇:網路正在減慢請求或讀取回應正文
