這似乎是它應該是一個衆所周知的問題,但我一直沒能找到一個很好的解決方案,這(既不是來自我的大腦也不是互聯網)。多個請求單個響應同步
首先,讓我們一個很簡單的例子:
mutex request <-- init to 0
mutex response <-- init to 0
Service thread (Guy S):
while not finished
wait(request)
do stuff
signal(response)
Someone requestion service (Guy U):
signal(request)
wait(response)
do stuff with results
到目前爲止好。 U
(用戶)信號S
(服務),並等待其響應。一切都很好。
現在想象一下,如果有很多用戶,請求相同的服務。現在,服務的性質使得結果隨時間變化(更確切地說週期性)。因此,如果10個用戶要求的服務更多或在同一時間少,該服務可以安全地只運行一次。
,想到的第一件事情是這樣的:
Guy S:
while not finished
wait(request)
do stuff
trywait(request)
broadcast(response)
Guy U:
signal(request)
wait(response)
do stuff with results
的不同,這裏是這樣的,首先S
trywait
S於請求時,它有效地設置爲0,因此,如果很多人已經暗示它,只有一個請求會通過。當然,互斥量的上限爲1,所以所有額外的信號累積到1,這將被trywait
刪除。第二個變化是,S
將broadcast
的響應,這樣所有的U
s就可以解鎖。
看起來不錯乍一看,但有一個問題吧。試想一下,處決的順序如下:
Guy S: Guy U1: Guy U2:
wait(request)
signal(request)
working
signal(request)
wait(response)
working
trywait(request)
broadcast(response)
wait(response)
working
(loop)
如果你仔細觀察,U2
被阻止,除非有人再次發送一個請求(上帝知道將來時)。很壞。
即使單個用戶,這可能發生:
Guy S: Guy U:
wait(request)
signal(request)
working
trywait(request)
broadcast(response)
wait(response)
(loop)
誰能想出了一個好主意,或直接我一個已知的算法?
附加信息:
S
只是定期有新的數據提供,而是基於應用程序,用戶可以決定得到零星的數據(通過請求),而不是週期性的。如果用戶請求太快,我會讓他等待下一段時間,所以這不是問題。- 我有機會,以饗讀者 - 寫鎖,條件變量,信號燈和互斥。讀者作家看起來很有希望獲得響應鎖定,但仍不清楚所有用戶何時通過了他們的
wait(response)
部分。
'如果東西需要重做'的部分已經在那裏。爲簡單起見,我已將其刪除。問題是,考慮兩個用戶:信號(請求)和服務喚醒,做一些東西和信號(響應)。有了這個信號,只有一個用戶會醒來,另一個用戶會捱餓。我可以使用信號量而不是互斥量,然後這個代碼(作爲我的原始代碼)都可以工作,除了現實中「需要重做的東西」並不那麼清楚(在我的應用程序中) – Shahbaz 2012-04-05 21:48:18
我的目標是獲得類似這個:「如果在服務一個請求的過程中,另一個請求到來,那麼最後兩個都會發出信號,因爲它們兩個都會得到相同的結果,如果不是,每當下一個請求服務時它都會服務。」雖然我說這項任務本質上是週期性的,但這並不完全正確。我有兩種類型的服務,其中一種是定期的,我可以很容易地確定「是否需要重做」。另一個是用戶的擴展,具有我無法預測的任何功能。 – Shahbaz 2012-04-05 21:50:20
@Shahbaz:我假設信號量;我的錯。 (顯然)你比我更瞭解上下文,但是如果另一個消費者沒有完成他的請求(而不是剛剛完成),結果是不同的,並且沒有其他標準來確定結果,那麼似乎有點偏離。例如,如果服務記錄了最後一次請求處理的時間,並且在某個窗口內出現的任何新請求獲得了相同的結果,將很容易實現。 – 2012-04-06 00:52:27