473,569 Members | 2,872 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Multithread wait for empty queue

I have a multithreaded application that manipulates a Queue:

protected Queue outputQueue;

when I add elements to the queue I use a critical section

private void Add(OutputRecor d record)
{
lock(outputQueu e)
{
// Add the element
outputQueue.Enq ueue(record);
}
}

when I remove an element from the queue I do something similar:

private OuputRecord Remove()
{
OutputRecord record;

lock (outputQueue)
{
// Remove the element
record = (OutputRecord) outputQueue.Deq ueue();
}
return record;
}

Now I want to be able to have a process that adds an element and then
waits until the queue is empty. What is the best way to do this? I
thought of creating an additional object called emptyOutputQueu e and
creating a WaitAdd function:

private bool WaitAdd(OutputR ecord record)
{
lock(emptyOutpu tQueue)
{
Add(record);
if (! Monitor.Wait(em ptyOutputQueue, 20000))
return false;
}
return true;
}

and changing the Remove function to be something like this

private OuputRecord Remove()
{
OutputRecord record;

lock (outputQueue)
{
// Remove the element
record = (OutputRecord) outputQueue.Deq ueue();

if (outputQueue.Co unt == 0)
{
lock (emptyOutputQue ue)
{
Monitor.PulseAl l(emptyOutputQu eue);
}
}
}
}
But I am not sure that the WaitAdd function will actually wait if the
queue is not empty. Any suggestions of what is the best solution?

Thanks

Jeronimo

Jul 21 '05 #1
4 3527
Jeronimo Bertran <je************ **@newsgroup.no spam> wrote:
I have a multithreaded application that manipulates a Queue:
<snip>
But I am not sure that the WaitAdd function will actually wait if the
queue is not empty. Any suggestions of what is the best solution?


For a start, I'd try to use a single lock - your current solution
acquires the two locks in different orders, which means you could have
deadlock.

If you have to use two locks (which you may) you should make sure you
always acquire them in the same order. I'd try to avoid calling other
methods which are going to do locking from within a method which
already locks - it'll make it easier to see this kind of problem.

I don't have time to come up with a solution for you right now, but I
can have another look tonight if you haven't solved it by then.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #2
Have a producer/consumer blocking queue here.
http://codeproject.com/csharp/BoundedBlockingQueue.asp
http://channel9.msdn.com/ShowPost.aspx?PostID=50960 (same Q with a server
example)

That also sounds a bit like a Reverse Sensing Semaphore, so you can check
this out too for some ideas:
http://codeproject.com/csharp/Dijkst...gSemaphore.asp

Using my queue above, your consumer could just call the TryDequeue() method
in its loop which will return False if the queue is empty. However, if your
producer(s) are still producing, this empty state may last for only a timer
tick or so as a producer may be right behind waiting to write. You may have
also *just missed an Empty state if another consumer grabbed the last
element and a producer just added one - you missed the empty state. A reset
event may be in order. If you describe the problem space in more detail, I
may be able to come up with a better idea. You may find what you need in
the code. Please let us know. Cheers.
--
William Stacey, MVP
http://mvp.support.microsoft.com

"Jeronimo Bertran" <je************ **@newsgroup.no spam> wrote in message
news:#5******** ******@TK2MSFTN GP14.phx.gbl...
I have a multithreaded application that manipulates a Queue:

protected Queue outputQueue;

when I add elements to the queue I use a critical section

private void Add(OutputRecor d record)
{
lock(outputQueu e)
{
// Add the element
outputQueue.Enq ueue(record);
}
}

when I remove an element from the queue I do something similar:

private OuputRecord Remove()
{
OutputRecord record;

lock (outputQueue)
{
// Remove the element
record = (OutputRecord) outputQueue.Deq ueue();
}
return record;
}

Now I want to be able to have a process that adds an element and then
waits until the queue is empty. What is the best way to do this? I
thought of creating an additional object called emptyOutputQueu e and
creating a WaitAdd function:

private bool WaitAdd(OutputR ecord record)
{
lock(emptyOutpu tQueue)
{
Add(record);
if (! Monitor.Wait(em ptyOutputQueue, 20000))
return false;
}
return true;
}

and changing the Remove function to be something like this

private OuputRecord Remove()
{
OutputRecord record;

lock (outputQueue)
{
// Remove the element
record = (OutputRecord) outputQueue.Deq ueue();

if (outputQueue.Co unt == 0)
{
lock (emptyOutputQue ue)
{
Monitor.PulseAl l(emptyOutputQu eue);
}
}
}
}
But I am not sure that the WaitAdd function will actually wait if the
queue is not empty. Any suggestions of what is the best solution?

Thanks

Jeronimo


Jul 21 '05 #3
William,

Thanks for the article... I could change the behavior of my queue to
look similar to what you have so that instead of blocking until the
queue is empty, block when the queue is full. Here is a more detailed
description of what I was trying to achieve:

Just like in your example, I am using the output Queue to send packets
over the network. For most packet types, I enqueue the data and the
communication thread dequeues and sends the data over the network. I
could use the locking queue in your example when calling Enqueue,
although right now I am simply returning false when the queue is full
(non blocking version).

Now, for some special packet types I wanted to make sure that the packet
was sent before I enqueued the next packet. For this reason, I wanted
to enqueue and then wait until the queue was empty before calling
enqueue for the next element. I understand that it is possible that the
queue never empties if another producer keeps adding elements but my
outputQueue in reality is almost always empty.

I am going to try to change the behavior and use your blocking queue and
simply block when the outputQueue is full. In my implenetation I will
use the nonblocking version of dequeue.

I will let you know if I run into problems.

Thanks again,

Jeronimo
Using my queue above, your consumer could just call the TryDequeue()
method in its loop which will return False if the queue is empty.
However, if your producer(s) are still producing, this empty state may
last for only a timer tick or so as a producer may be right behind
waiting to write. You may have also *just missed an Empty state if
another consumer grabbed the last element and a producer just added
one - you missed the empty state. A reset event may be in order. If
you describe the problem space in more detail, I may be able to come
up with a better idea. You may find what you need in the code.
Please let us know. Cheers.


Jul 21 '05 #4
Are you using UDP? If so, then you still need to check if the packet was
actually received via some ack. If TCP, then the packets will be in order
so not sure why you need to worry about it. I probably miss something in
your needs. Let me know if can help more. Cheers.

--
William Stacey, MVP
http://mvp.support.microsoft.com

"Jeronimo Bertran" <je************ **@newsgroup.no spam> wrote in message
news:Xn******** *************** *********@207.4 6.248.16...
William,

Thanks for the article... I could change the behavior of my queue to
look similar to what you have so that instead of blocking until the
queue is empty, block when the queue is full. Here is a more detailed
description of what I was trying to achieve:

Just like in your example, I am using the output Queue to send packets
over the network. For most packet types, I enqueue the data and the
communication thread dequeues and sends the data over the network. I
could use the locking queue in your example when calling Enqueue,
although right now I am simply returning false when the queue is full
(non blocking version).

Now, for some special packet types I wanted to make sure that the packet
was sent before I enqueued the next packet. For this reason, I wanted
to enqueue and then wait until the queue was empty before calling
enqueue for the next element. I understand that it is possible that the
queue never empties if another producer keeps adding elements but my
outputQueue in reality is almost always empty.

I am going to try to change the behavior and use your blocking queue and
simply block when the outputQueue is full. In my implenetation I will
use the nonblocking version of dequeue.

I will let you know if I run into problems.

Thanks again,

Jeronimo
Using my queue above, your consumer could just call the TryDequeue()
method in its loop which will return False if the queue is empty.
However, if your producer(s) are still producing, this empty state may
last for only a timer tick or so as a producer may be right behind
waiting to write. You may have also *just missed an Empty state if
another consumer grabbed the last element and a producer just added
one - you missed the empty state. A reset event may be in order. If
you describe the problem space in more detail, I may be able to come
up with a better idea. You may find what you need in the code.
Please let us know. Cheers.


Jul 21 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

29
4200
by: Paul L. Du Bois | last post by:
Has anyone written a Queue.Queue replacement that avoids busy-waiting? It doesn't matter if it uses os-specific APIs (eg WaitForMultipleObjects). I did some googling around and haven't found anything so far. Because I know someone will ask: no, the busy-waiting hasn't been a problem in my app. I'm just interested in reading the code. p
8
4057
by: Jun | last post by:
hi, just want to know if std::queue empty() is thread safe (running on 2 or more thread)... so i can do, if( !queue.empty() ) { lock() .... unlock()
4
324
by: Jeronimo Bertran | last post by:
I have a multithreaded application that manipulates a Queue: protected Queue outputQueue; when I add elements to the queue I use a critical section private void Add(OutputRecord record) { lock(outputQueue) {
5
2571
by: mrkbrndck | last post by:
Please see the code below as I am trying to use multithreading for copying files to a new location in a way that improves performance of the client windows application. The problem occurs when 2 or more threads are created, the ImportOneFile method attempts to add a previously added file. If I allow 4 maximum threads and process 4 files,...
12
5250
by: Perecli Manole | last post by:
I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse. I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block protecting a resource. Thread 2 and 3 also have a SyncLock block protecting the same resource and after executing some code in their blocks...
0
1703
by: NvrBst | last post by:
I want to send a bunch of keys to an external window using PostMessage. I send a "KEYDOWN" message (then have to wait for the program to produce the CHAR message) then send the "KEYUP" message. Sometimes I have to only wait 1ms, others I have to wait up to 10ms. Always waiting 10ms for the long messages makes the typing looks slower... Is...
2
5285
by: tikcireviva | last post by:
Hi Guys, I've done a mulithread queue implementation on stl<queue>, my developement environment is on VC6 as well as FC3. Let's talks about the win32 side. The suspected memory leak is find after I've run through my unit test cases. Test Case:
6
4415
by: gskbond | last post by:
Following is my logic to traverse level by level an mway search tree.... (Yeah I finally used templates to implement a queue... :) ) void mWayTree:: TraverseLevelOrder(Node *root,int lvl) { int i; int level; Dq<Node *> Q; Node *tmp;
5
2801
by: randysimes | last post by:
I have to make a queue utilizing a linked list for an assignment. When I Push() an item to the queue, and try to Pop() or return the Front() element, it says the queue is empty. When I Push() another element to the queue and Pop() or return the Front(), the first entered element is returned. Say I enter 4 element and then Pop(), it pops elements...
0
7703
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7619
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7930
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7983
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5514
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3662
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2118
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
950
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.