Question about boxing and using Monitor::Enter / Monitor::Exit.

  • Thread starter Thread starter Ken Varn
  • Start date Start date
K

Ken Varn

If I have a value type such as int that I want to protect in a
multi-threaded situation, Is it safe to use Monitor::Enter(__box(value))?
I am thinking that a different object pointer is generated each time and
thus the protection is not insured. Is this true or not?

Example:

public _gc class MyClass
{
int Value;

void IncValue()
{
Monitor::Enter(__box(Value));
Value++;
Monitor::Exit(__box(Value));
}
};


--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
-----------------------------------
 
Ken said:
If I have a value type such as int that I want to protect in a
multi-threaded situation, Is it safe to use Monitor::Enter(__box(value))?
I am thinking that a different object pointer is generated each time and
thus the protection is not insured. Is this true or not?

Example:

public _gc class MyClass
{
int Value;

void IncValue()
{
Monitor::Enter(__box(Value));
Value++;
Monitor::Exit(__box(Value));
}
};

Your hunch is correct. That's not going to work for the reason you say. You
can synchronize on MyClass, or if that feels too coarse, you can create a
new System::Object and dedicate it to protecting Value. The latter is
probably the better approach.
 
Yikes! Don't you guys make voting machines?

Your surmise is correct, what you've posted won't work.

You have two main approaches.

1) System.Threading.Interlocked.Increment is an atomic (and therefore
somewhat thread-safe) operation.

2) Have a private locking object; this will allow more complex atomic
operations.

int Votes;
Object Locking; // = new Object(); in the constructor

void PlaceVote()
{
__try // In case you're going to do something that might throw.
{
Monitor::Enter( Locking );
// NB Don't use Enter( this ) or Enter( typeof(...) )

++Votes;
}
__finally
{
Monitor::Exit( Locking );
}
}

C# has a shortcut for this pattern, namely the lock statement.

Hope that helps,
Stu
 
Thanks for the info.

BTW. I do not work on voting machines. That is a completely different
division.

--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
-----------------------------------
Stu Smith said:
Yikes! Don't you guys make voting machines?

Your surmise is correct, what you've posted won't work.

You have two main approaches.

1) System.Threading.Interlocked.Increment is an atomic (and therefore
somewhat thread-safe) operation.

2) Have a private locking object; this will allow more complex atomic
operations.

int Votes;
Object Locking; // = new Object(); in the constructor

void PlaceVote()
{
__try // In case you're going to do something that might throw.
{
Monitor::Enter( Locking );
// NB Don't use Enter( this ) or Enter( typeof(...) )

++Votes;
}
__finally
{
Monitor::Exit( Locking );
}
}

C# has a shortcut for this pattern, namely the lock statement.

Hope that helps,
Stu
 
Thanks for the info. I am curious about one thing though. Is there any
difference in using an object for synchronization using Monitor vs. using a
Mutex object?

--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
 
Ken said:
Thanks for the info. I am curious about one thing though. Is there any
difference in using an object for synchronization using Monitor vs. using a
Mutex object?

For basic synchronization in a single process, no. However, with Mutex you
can create a named mutex to use across processes, and you can wait on
multiple Mutexes and other WaitHandle-derived objects in a single
WaitHandle::WaitAny or WaitAll call. On the other hand, Monitor supports
condition variable programming with its Pulse members. For more on all this,
see:

Threading Objects and Features
http://msdn.microsoft.com/library/d...pguide/html/cpconThreadingObjectsFeatures.asp
 
Back
Top