Synchronized Producer & Consumer with Circular buffer
I've got a producer and a consumer. The producer writes fixed size items on a given shared memory area, and the consumer retrieves them.
The producer can be noticeably slower or faster than the consumer, randomly.
What we want is that
If the producer is running faster than the consumer, when it fills the circular buffer, it keeps writing on the oldest frames (other than the one that the consumer is consuming, of course - I stress this point, producer and consumer must be synchronized in the solution, because they are unrelated processes).
If, instead, the consumer is faster than the producer, it must wait for a new frame and consume it when it's there.
I found implementations of producer/consumers with circular buffers, but only ones that didn't respect the first request (ie, if the circular buffer is full, they wait for the consumer to finish, while what I want is to overwrite the oldest frames).
I'd prefer not to roll my own (pron开发者_如何学JAVAe to bugs) solution, but use a pre-canned, tested one. Can someone point me to a good C implementation? (C++ is also ok).
Many thanks.
Basically when the consumers are slow, it means that no one is using the buffer, so there is no difference between dropping the new frames and overriding the old frames. So maybe the following code can help. The producerRTLock cannot lock the buffer because there are consumers using the bufffer and therefore at the application level you can indicate to drop the frames.
class SampleSynchronizer {
mutex mux;
condition_variable con_cond;
unsigned int con_num;
condition_variable pro_cond;
bool prod;
public:
SampleSynchronizer(): con_num(0), prod(false) {
}
void consumerLock() {
unique_lock<mutex> locker(mux);
while(prod)
pro_cond.wait(locker);
con_num++;
}
void consumerUnlock() {
lock_guard<mutex> locker(mux);
con_num--;
con_cond.notify_one();
}
void producerLock() {
unique_lock<mutex> locker(mux);
while(con_num > 0)
con_cond.wait(locker);
prod = true;
}
bool producerRTLock() {
lock_guard<mutex> locker(mux);
if(con_num > 0)
return false;
prod = true;
return true;
}
void producerUnlock() {
lock_guard<mutex> locker(mux);
prod = false;
pro_cond.notify_all();
}
};
Sounds like you want to use a double ended queue which is provided in C++'s Standard Template Library (STL). But that uses C++, not C. If your producer and consumer are different threads then you'll also need a mutex to protect the queue structure.
精彩评论