我想實現一個單一生產者和單個消費者的緩衝區,其中只有消費者可能被阻止。這裏重要的細節是,如果隊列已滿,生產者可以刪除更新。單生產者/消費者循環緩衝區,只阻止消費者
我已經考慮轉換一個等待免費的實現,但乍一看似乎沒有簡單的方法來通知消費者新數據已到達而不會丟失通知。所以,我在非常簡單的方法解決下面,使用計數信號(省略了一些錯誤處理細節的清晰度):
Object ar[SIZE];
int head = 0, tail = 0;
sem_t semItems; // initialized to 0
void enqueue(Object o) {
int val;
sem_getvalue(&semItems, &val);
if (val < SIZE - 1) {
ar[head] = o;
head = (head + 1) % SIZE;
sem_post(&semItems);
}
else {
// dropped
}
}
Object dequeue(void) {
sem_wait(&semItems);
Object o = ar[tail];
tail = (tail + 1) % SIZE;
return o;
}
是否有與此代碼的任何安全問題?我很驚訝沒有在流行文獻中的任何地方看到它的實現。另外一個問題是sem_post()
是否會阻塞(在linux下引用futex_wake()
)。當然也歡迎更簡單的解決方案。
編輯:編輯代碼在閱讀器和作者之間留下空間(請參閱Mayurk的回覆)。
我知道爲什麼你只需要阻止消費者? –
@SumitGemini當有大量的流量時,消費者應該比生產者慢,因爲生產者會與硬件進行交談。這只是我看到的一種可能的方法,可能是隱含的CAS循環實際上使其變得更糟。 – wds
@SumitGemini剛剛遇到了一個針對本地C++信號量的提議,它更好地解釋了它:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2043.html#SemaphoreTypes – wds