Home All Groups Group Topic Archive Search About
Author
3 Apr 2005 11:34 PM
laimis
Hey guys,

I am writing this one multithreaded app where I do synchronization
between producer/consumer with boolean flags and busy waiting. How much
more efficient is Monitor.Wait(syncobj) and Monitor.Signal(syncobj)
combinations?

Author
4 Apr 2005 6:20 AM
Jon Skeet [C# MVP]
laimis <simu***@iit.edu> wrote:
> I am writing this one multithreaded app where I do synchronization
> between producer/consumer with boolean flags and busy waiting. How much
> more efficient is Monitor.Wait(syncobj) and Monitor.Signal(syncobj)
> combinations?

Much, much, much more efficient. (You probably need to use boolean
flags as well, but busy waiting is a really bad idea.)

See http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml for a
producer/consumer queue (it's about half way down).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Are all your drivers up to date? click for free checkup

Author
5 Apr 2005 4:17 AM
laimis
Yeah, consumer/producer based on wait/pulse sounds nice. Here is my
concern and situation:

Let's say I have one buffer that two threads will share (instead of a
queue). One thread will place data into it, the other thread will read
data out of it. How to make sure that producer, after placing the data
in, doesn't acquire the lock faster than the consumer and overwrite the
already existing data in the buffer? It is not a problem in a queue
since nothing will be overwritten, just an extra queue item will be
enqueued.

Would it be a bad approach to introduce some flag that producer sets
when it finishes filling up buffer and doesn't attempt to fill the
buffer unless the flag is unset. Reader meanwhile reads the buffer once
it acquires the lock and unsets the flag once it is done reading to mark
the buffer ready to be filled.


Jon Skeet [C# MVP] wrote:
Show quoteHide quote
> laimis <simu***@iit.edu> wrote:
>
>>I am writing this one multithreaded app where I do synchronization
>>between producer/consumer with boolean flags and busy waiting. How much
>>more efficient is Monitor.Wait(syncobj) and Monitor.Signal(syncobj)
>>combinations?
>
>
> Much, much, much more efficient. (You probably need to use boolean
> flags as well, but busy waiting is a really bad idea.)
>
> See http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml for a
> producer/consumer queue (it's about half way down).
>
Author
5 Apr 2005 6:29 AM
Jon Skeet [C# MVP]
laimis <simu***@iit.edu> wrote:
Show quoteHide quote
> Yeah, consumer/producer based on wait/pulse sounds nice. Here is my
> concern and situation:
>
> Let's say I have one buffer that two threads will share (instead of a
> queue). One thread will place data into it, the other thread will read
> data out of it. How to make sure that producer, after placing the data
> in, doesn't acquire the lock faster than the consumer and overwrite the
> already existing data in the buffer? It is not a problem in a queue
> since nothing will be overwritten, just an extra queue item will be
> enqueued.
>
> Would it be a bad approach to introduce some flag that producer sets
> when it finishes filling up buffer and doesn't attempt to fill the
> buffer unless the flag is unset. Reader meanwhile reads the buffer once
> it acquires the lock and unsets the flag once it is done reading to mark
> the buffer ready to be filled.

If you're going to do that, you might want to think about having two
producer/consumer queues, one of which works each way - when the
consumer has consumed the data, it can "produce" an event saying "I'm
finished" which the consumer can consume.

I'd think about using different buffers for different work items though
- that would allow more parallelism. (You could always have a stock of
them, and reuse them when appropriate.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Author
7 Apr 2005 7:19 AM
laimis
Jon Skeet [C# MVP] wrote:
Show quoteHide quote
> laimis <simu***@iit.edu> wrote:
>
>>I am writing this one multithreaded app where I do synchronization
>>between producer/consumer with boolean flags and busy waiting. How much
>>more efficient is Monitor.Wait(syncobj) and Monitor.Signal(syncobj)
>>combinations?
>
>
> Much, much, much more efficient. (You probably need to use boolean
> flags as well, but busy waiting is a really bad idea.)
>
> See http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml for a
> producer/consumer queue (it's about half way down).
>

As always, excellent discussion with Jon turns into nice solutions :)

Anyways man, what I did eventually is this:

Created a syncronization bucket that
    - contains a queue for producer/consumer
    - syncronization code to support multithreading
    - flag indicating if producer/consumer should clean up and exit

Network Receiver (producer)
    - places the data into the queue through the sync bucket

Disk Writer (consumer)
    - obtains data from the queue through the sync bucket

The solution works very nice. All synchronization is done through lock
and Monitor.Signal and Monitor.Wait. Producer/consumer run on different
threads and everything is working perfectly. I did various test and
actually left the application running all night, getting data from the
network stream, processing on the writer side and written to the disk.
No CPU spikes, smooth stream processing and downloading, and no crazy
memory consumption. Queue goes up to 3 items, but that's about it. I
need to do more stress testing, but I believe I got what I wanted it.

Thanks for the discussion and pointers Jon!
Author
4 Apr 2005 8:10 PM
William Stacey [MVP]
You could also check out a consumer/producer sample I posted in the Sandbox
at Channel9.
http://channel9.msdn.com/ShowPost.aspx?PostID=50960

Shows a blocking queue implementation inside a simple server using a GUI to
make it easier to visualize.

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

Show quoteHide quote
"laimis" <simu***@iit.edu> wrote in message
news:uHsOwWKOFHA.1396@TK2MSFTNGP10.phx.gbl...
> Hey guys,
>
> I am writing this one multithreaded app where I do synchronization
> between producer/consumer with boolean flags and busy waiting. How much
> more efficient is Monitor.Wait(syncobj) and Monitor.Signal(syncobj)
> combinations?
>

Bookmark and Share