Implementing thread safe Queue collection object

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

I've been reading the online documentation for the System.Collections.Queue
object on how to implement a threadsafe Queue object.

I understand the basics, by using the wrapper returned by Synchronised
method, but I'm not sure how to implement it between 2 threads. Has anyone
got any suggestions or examples?

Thanks
Macca
 
When you say "betweeen 2 threads" I'm not sure I understand the intent. The
samples online are very simple:

Queue myCollection = new Queue();
lock( myCollection.SyncRoot ) {
foreach ( Object item in myCollection ) {
// Insert your code here.
}
}

Until the closing brace of the lock statement, no other thread can operate
on the Queue.
Peter
 
Macca said:
Hi,

I've been reading the online documentation for the
System.Collections.Queue
object on how to implement a threadsafe Queue object.

I understand the basics, by using the wrapper returned by Synchronised
method, but I'm not sure how to implement it between 2 threads. Has anyone
got any suggestions or examples?

Thanks
Macca

If you mean to send stuff from one thread to another then you need to write
your own wrapper and use
Monitor.Wait(q) to wait for the Q to become non-empty and
Monitor.PulseAll(q) when you put something on it.

i.e. something like:

class MyQ
{
private Queue q;

public void Enqueue(MyClass x)
{
lock(q)
{
q.Enqueue(x);
Monitor.PulseAll(q);
}
}

public MyClass Dequeue(MyClass x)
{
lock(q)
{
while(q.Empty)
Monitor.Wait(q);
return (MyClass)q.Dequeue();
}
}
}

Note that Synchronized is not used as the Queue is not exposed and locking
is handled in the methods.
 
Thanks for the reply Peter.

What I mean is that I have one thread that adds entries to the queue while
another takes them off and processes them. I'm assuming the queue will be a
shared item between the 2 threads although not sure exactly where is best
place to store it. In first thread?

While items are being processed it should be possible to add entries to the
queue at the same time although if processing thread is fast enough this may
not be a requirement.

I assume the processing thread will have to poll the queue to see if there
is anything in the queue first although it would be nice to have this event
driven rather than having to poll.

I would have thought this is not an uncommon scenario, one thread building
up the queue while another extracts entries and processes them?

What I dont want is the processing of the entries to block entries being put
on the queue therefore the need for two threads.

What do you think?

Regards
Macca
 
Macca said:
Thanks for the reply Peter.

What I mean is that I have one thread that adds entries to the queue while
another takes them off and processes them. I'm assuming the queue will be a
shared item between the 2 threads although not sure exactly where is best
place to store it. In first thread?

You don't "store" items in threads.

It sounds like you really want a producer/consumer queue. See half way
down
http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml for some
sample code.
While items are being processed it should be possible to add entries to the
queue at the same time although if processing thread is fast enough this may
not be a requirement.

I assume the processing thread will have to poll the queue to see if there
is anything in the queue first although it would be nice to have this event
driven rather than having to poll.

The version I've got on the page referenced above blocks on the call to
Consume until a work item is ready. You'd therefore end up with a
thread which did nothing but consume work items. You should be able to
modify the code appropriately if you want though.

Jon
 
Back
Top