Mutex

  • Thread starter Thread starter dercon
  • Start date Start date
D

dercon

I'm developing a multi-threaded application which contains a global
collection.
The main thread adds objects to the global collection while the worker
threads (between 10-20) read (for each... next) from the global
collection. I'm getting an error when the worker threads try to read
from the collection while the main thread is either adding or removing
items on the global collection. On the main thread I've tried using a
synclock when adding or removing items from the global collection but
that does not seem to be helping. I remember back in college my prof
was talking about Semaphores, Mutex, and Monitors... is there any such
construct in vb.NET that i can use?

:\\derian
 
dercon said:
I'm developing a multi-threaded application which contains a global
collection.
The main thread adds objects to the global collection while the worker
threads (between 10-20) read (for each... next) from the global
collection. I'm getting an error when the worker threads try to read
from the collection while the main thread is either adding or removing
items on the global collection. On the main thread I've tried using a
synclock when adding or removing items from the global collection but
that does not seem to be helping. I remember back in college my prof
was talking about Semaphores, Mutex, and Monitors... is there any such
construct in vb.NET that i can use?

Yes, if you check the .NET docs, you will find that there is a Mutex class,
but SyncLock should work. You're probably not using an object that is
available to all threads or is not a ref type. For example, using Me in a
Class is not guarenteed to work with SyncLock, but using the Class name in a
shared method is. One option is to make a lock object collection (or even a
single variable) and place it in a global module. Using the collection
itself as your locking mechanism should even work.

HTH,
Jeremy
 
dercon said:
I'm developing a multi-threaded application which contains a global
collection.
The main thread adds objects to the global collection while the worker
threads (between 10-20) read (for each... next) from the global
collection. I'm getting an error when the worker threads try to read
from the collection while the main thread is either adding or removing
items on the global collection. On the main thread I've tried using a
synclock when adding or removing items from the global collection but
that does not seem to be helping. I remember back in college my prof
was talking about Semaphores, Mutex, and Monitors... is there any such
construct in vb.NET that i can use?

:\\derian

First off, you must realize that iteration using For Each, even if
collection is syncronized is not thread safe... Exactly for the reasons you
specify. If a collection is modified by another thread during the
iteration, it invalidates the enumerator and throws an exception. There is
no way around this really except

A. Lock the collection throught the iteration
' code to add
SyncLock globalCollection
globalCollection.Add(new mytype)
end synclock

' code to iterate.
SyncLock globalCollection
For Each item as mytype in globalCollection
' do stuff with item
next
end synclock

With the above you are required to make sure that you use the synclock when
ever you want to add, remove, or iterate items. This is pretty inefficient,
since it is going to cause all threads to wait while one thread iterates the
collection.

B. Catch the exception.

You may want to go with option b. Again, you will need to catch the
exception thrown when the enumerator becomes invalid - in that case it may
be more logical to not use for each. You may want to use the IEnumerator
interface directly. This is air code so, you will definately want play
around with it :)

Dim enumerator as IEnumerator = globalCollection.GetEnumerator()
dim o as myobjecttype

do while true
try
if enumeator.movenext()
o = directcast(enumerator.current, myobjecttype)
' do stuff with object...
else
exit do
end if
catch
enmerator = globablCollection.GetEnumerator()
end try
loop

As for mutex, etc. There is a mutex class, but mutex's are really designed
for process syncronization rather then thread sync. They are global kernal
objects. What you really want is a critical section - which is what the
monitor class in System.Threading provides. Of course you don't often have
to use it directly because SyncLock is really just a shortcut for using
System.Threading.Monitor :) There is also the ManualResetEvent class and
the AutoResetEvent class, which can be used to wait for events to occur on
other threads. One interesting class you may want to look at is the
ReaderWriterLock class. It is sort of like the Monitor class, but is
optimized for use with Single writer, multiple reader scenarious... Anyway,
just some thoughts and ramblings...

HTH,
Tom Shelton
 
Thanks a lot guys... your post have given me some very helpful
insights. I'll let you know how the final project turns out.

:\\derian
 
Back
Top