php小編香蕉帶來了一篇精彩的文章,講述了golang中切片的并發(fā)映射。在這篇文章中,我們將了解如何在并發(fā)環(huán)境中使用切片進(jìn)行映射操作,并解釋了為什么切片在并發(fā)編程中非常有用。通過使用golang的并發(fā)機(jī)制,我們可以在多個goroutine中同時訪問和修改切片,從而提高程序的性能和效率。無論你是初學(xué)者還是有經(jīng)驗的golang開發(fā)者,這篇文章都將給你帶來有價值的知識和實踐技巧。讓我們一起來探索golang中帶有切片的并發(fā)映射吧!
問題內(nèi)容
在該領(lǐng)域的一位開發(fā)人員幾個月前離開后,我一直在嘗試解決并發(fā)問題,但我找不到解決此問題的適當(dāng)方法。
對于上下文,我們將客戶數(shù)據(jù)加載到如下結(jié)構(gòu)中:
[ 鍵 ] -> { 值 }
[客戶特定哈希] -> {數(shù)據(jù)點/文件切片}
示例 – 格式確實很糟糕,抱歉:
[a60d849ad97bfb833e1096941]
->
{
{ StartDate: '01-02-2022', EndDate: '28-02-2022', DataFrames: [1598,921578,12981,21749,192578...]},
{ StartDate: '01-03-2022', EndDate: '28-03-2022', DataFrames: [1234,1567,6781,126978...]},
}
登錄后復(fù)制
以上是因為我們有 100,000 名客戶,并且每天晚上都會啟動一個流程,根據(jù)每個客戶的哈希值(或?qū)嶋H上是一個存儲桶)來整合數(shù)據(jù)。在處理數(shù)據(jù)幀之前,我們會遍歷切片并將數(shù)據(jù)幀“合并”成一個大的數(shù)據(jù)幀,其中包含許多法律/會計規(guī)則。
它在 goroutine 中運(yùn)行,以盡快索引所有數(shù)據(jù)點。
所以實現(xiàn)本質(zhì)上是一個 sync.Map[string, []DataFrame] 但我注意到雖然映射操作受到保護(hù),但附加到數(shù)據(jù)幀切片卻不受保護(hù)。每個哈希值每晚在該切片中可能有大約 20-30 個文件引用。
在過去的兩年里,客戶數(shù)據(jù)很有可能被錯誤地合并,我的任務(wù)是修復(fù)它。在sync.map之前,他們再次使用了帶有Map的RWMutex,但不是切片,它指向本文作為指南。
首先,包含切片的 Map 的想法是適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)嗎?
我嘗試創(chuàng)建一個基于 RWMutex 的切片處理程序,但想知道 Map 是否可以有一個 chan DataFrame 來代替在索引客戶文件時放入,然后一旦完成,第二步將其合并到一個數(shù)組中(如len(chanx)) 會被知道嗎?
我主要來自 Java,所以我可能對一些術(shù)語感到困惑,所以我很抱歉。
解決方法
您有兩個不同的問題:
-
更新地圖時出現(xiàn)并發(fā)問題
更新地圖條目時出現(xiàn)并發(fā)問題
sync.Map 將防止 1,但不能防止 2。
解決這個問題的一種方法是:
sync.Map[string, *DFrame]
登錄后復(fù)制
哪里
type DFrame struct {
sync.RWMutex
Data []DataFrame
}
登錄后復(fù)制
一旦從地圖中獲取條目,您應(yīng)該 Lock 或 RLock 它,然后使用數(shù)據(jù)。這不僅僅限于切片的附加。即使您只從數(shù)據(jù)幀中讀取,您也必須 RLock 該結(jié)構(gòu)。
因此,如果您要附加新的數(shù)據(jù)框:
df := &DFrame{}
entry,_:=m.LoadOrStore(key, df)
dfEntry:=entry.(*DFrame)
dfEntry.Lock()
dfEntry.Data=append(dfEntry.Data, newDataFrame)
dfEntry.Unlock()
登錄后復(fù)制






