मुझे लगता है कि मेरे पास वह है जो आप खोज रहे हैं। यह लॉक फ्री रिंग बफर कार्यान्वयन है जो उत्पादक/उपभोक्ता को अवरुद्ध करता है। आपको केवल परमाणु प्राइमेटिव तक पहुंच की आवश्यकता है - इस उदाहरण में मैं जीसीसी के sync
फ़ंक्शंस का उपयोग करूंगा।
यह एक ज्ञात बग है - यदि आप 100% से अधिक बफर को ओवरफ़्लो करते हैं तो यह गारंटी नहीं दी जाती है कि कतार FIFO बनी हुई है (यह अभी भी उन्हें अंततः संसाधित करेगी)।
इस कार्यान्वयन पढ़ने पर निर्भर करता है/एक परमाणु आपरेशन (जो काफी संकेत के लिए गारंटी है) होने के रूप में बफर तत्वों लिख
struct ringBuffer
{
void** buffer;
uint64_t writePosition;
size_t size;
sem_t* semaphore;
}
//create the ring buffer
struct ringBuffer* buf = calloc(1, sizeof(struct ringBuffer));
buf->buffer = calloc(bufferSize, sizeof(void*));
buf->size = bufferSize;
buf->semaphore = malloc(sizeof(sem_t));
sem_init(buf->semaphore, 0, 0);
//producer
void addToBuffer(void* newValue, struct ringBuffer* buf)
{
uint64_t writepos = __sync_fetch_and_add(&buf->writePosition, 1) % buf->size;
//spin lock until buffer space available
while(!__sync_bool_compare_and_swap(&(buf->buffer[writePosition]), NULL, newValue));
sem_post(buf->semaphore);
}
//consumer
void processBuffer(struct ringBuffer* buf)
{
uint64_t readPos = 0;
while(1)
{
sem_wait(buf->semaphore);
//process buf->buffer[readPos % buf->size]
buf->buffer[readPos % buf->size] = NULL;
readPos++;
}
}
मुझे नहीं पता कि आप किस माहौल में हैं, लेकिन Win32 में आप WaitForMultipleObjects का उपयोग कर कतार के बिना एक ही समय में सभी कतारों पर उपभोक्ता प्रतीक्षा कर सकते हैं। –
मुझे खेद है, मैंने यह उल्लेख नहीं किया कि मैं मुख्य रूप से लिनक्स – ziu
पर काम करता हूं, अगर आपको वास्तविक उत्तर नहीं मिलेगा, तो इसके साथ कई बफर सिंक करने की हवा होगी: http://neosmart.net/ ब्लॉग/2011/waitformultipleobjects-and-win32-events-for-linux-and-read-write-locks-for-windows/ –