Reputation: 7519
I have two threads sharing a lock-free queue. The first thread enqueues stuff into the queue while the second thread waits for an event signal that there is new data in the queue for it to dequeue. Once it dequeues the item the event is reset.
//pseudo-code
dequeingThread()
{
WaitForEventSignal();
dequeue();
[..] // do stuff
ResetEvent();
}
Then I thought what if the first thread enqueues more than one item before the second thread finishes with the first one? Then it wouldn't recognize any event calls.
So I then thought about using a variable called availableEnqueues
and once the signal is triggered the second thread would keep dequeuingwhile(availableEnqueues > 0)
and once it's zero reset the event again.
//pseudo-code
dequeingThread()
{
WaitForEventSignal();
while(availableEnqueues > 0)
{
dequeue();
[..] // do stuff
availableEnqueues--;
}
ResetEvent();
}
But this would require a lock and Thread 1 cannot afford to lose even a tiny amount of time on locks and that's why I opted for a lock-free queue.
Then I thought of using two variables one called totalEnqueues
and another enqueueIndex
. The first written by the first thread and read by the second, and the second variable read and written by the second thread.
//pseudo-code
dequeingThread()
{
WaitForEventSignal();
while(totalEnqueues > enqueueIndex)
{
dequeue();
[..] // do stuff
enqueueIndex++;
}
ResetEvent();
}
So now since no thread touches each others variables I can avoid the lock. But something seems wrong to me with this solution. I am not even sure if I can skip the locks. Anyone has any better ideas?
Upvotes: 2
Views: 248
Reputation: 1477
Not entirely sure what your queueing/dequeueing is supposed to be doing, but...
If your 'dequeue' thread is meant to empty all elements whenever they are added (by some other thread that adds a queue item then sets an event), you could do something like:
//pseudo-code
dequeingThread()
{
WaitForEventSignal();
do{
ResetEvent();
dequeue();
[..] // do stuff
while( queue_not_empty )
}
if the other thread adds an entry, then (a) the queue will not be empty or (b) this thread sees the queue as empty, but the event will have been set after we reset it.
Also, if we spend some time in "doing stuff" and the queuer adds more than one item then this will take care of that.
Upvotes: 1