2 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
您需要一個(gè)互斥體來(lái)保護(hù)條件免受并發(fā)讀/寫(xiě)的影響,然后需要一個(gè)用于在希望再次執(zhí)行同步代碼時(shí)重置條件的方法。
type SomeClass struct {
conditionMu sync.Mutex
condition bool
}
func (c *SomeClass) SomeFunc() {
// Lock the mutex, so that concurrent calls to SomeFunc will wait here.
c.conditionMu.Lock()
if c.condition {
// Synchronous code goes here.
// Reset the condition to false so that any waiting goroutines won't run the code inside this block again.
c.condition = false
}
// Unlock the mutex, and any waiting goroutines.
c.conditionMu.Unlock()
}
// ResetCondition sets the stored condition to true in a thread-safe manner.
func (c *SomeClass) ResetCondition() {
c.conditionMu.Lock()
c.condition = true
c.conditionMu.Unlock()
}

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
這個(gè)問(wèn)題的其他答案是不正確的,因?yàn)樗鼈儾环蠁?wèn)題的要求。
如果將鎖添加到條件語(yǔ)句之外,則它將充當(dāng)屏障,并將強(qiáng)制所有例程在該位置同步。這不是這個(gè)問(wèn)題的重點(diǎn)。假設(shè)解析條件值需要很長(zhǎng)時(shí)間,我們不想一次檢查一個(gè)例程的值。我們希望讓每個(gè)進(jìn)程立即檢查條件,因此如果條件為假,我們可以繼續(xù)前進(jìn)而不會(huì)停止。
我們希望確保在條件不成立時(shí),goroutines 并行運(yùn)行。在方法內(nèi)部和條件語(yǔ)句外部添加鎖將不允許發(fā)生這種情況。
以下解決方案是正確的,通過(guò)了所有測(cè)試,表現(xiàn)良好。
解決方案 1:
使用 2 個(gè)嵌套條件語(yǔ)句,如下所示:
請(qǐng)注意,在這種情況下,如果條件為 false,則不會(huì)調(diào)用任何鎖,也不需要同步。一切都可以并行運(yùn)行。
type SomeClass struct {
conditionMu sync.Mutex
rwMu sync.RWMutex
additionalWorkRequired bool
}
func (c *SomeClass) SomeFunc() {
//Do some work ...
//Note: The condition is not shared, some routines can have false and some true at the same time, which is fine.
condition := true;
// All routines can check this condition and go inside the block if the condition is true
if condition {
c.rwMutex.Lock()
c.additionalWorkRequired = true
c.rwMutex.Unlock()
//Lock so other routines can wait here for the first one
c.conditionMu.Lock()
if c.additionalWorkRequired {
// Synchronous code goes here.
c.additionalWorkRequired = false
}
//Unlock so all other processors can move forward in parallel
c.conditionMu.unlock()
}
//Finish up the remaining work
}
解決方案 2:
使用同步/單次飛行中的功能,該功能可以自動(dòng)處理這種情況。do
從文檔中:
Do 執(zhí)行并返回給定函數(shù)的結(jié)果,確保一次只有一個(gè)給定密鑰正在執(zhí)行。如果出現(xiàn)重復(fù)項(xiàng),則重復(fù)調(diào)用方將等待原始文件完成并收到相同的結(jié)果。共享的返回值指示是否已將 v 提供給多個(gè)調(diào)用方。
編輯:
由于許多人似乎對(duì)這個(gè)問(wèn)題和答案感到困惑,因此我添加了一個(gè)用例,可能會(huì)使事情變得更加清晰:
1. Send a HTTP Request
2. If the server returns an error saying credentials are incorrect (This is condition):
2.1. Save current credentials in a local variable
2.2. Acquire the mutex lock
2.2.1. Compare the shared credentials with the ones in the local variable(This is the second condition)
If they are the same, then replace them with new ones
2.3. Unlock
2.4. Retry request
- 2 回答
- 0 關(guān)注
- 132 瀏覽
添加回答
舉報(bào)