|
-
August 13th, 2011, 03:04 PM
#1
A few questions about thread safety
Hello all,
I have a library with a few classes in it that run great in a single threaded environment, but I am getting more and more into multithreaded apps and even though I havent had problems yet, would like to avoid them by implementing thread safety. I realize it probably would have been better in native c++, but chose to focus on managed c++ when I taught myself and will convert it when I start teaching myself native c++.
Anyways, this was written in ms C++/cli 2008. All of the classes are immutable, once the object is created, it never changes that values. The assignment and math operators all create a new object and return that, however, I do not believe that it is thread safe in that if an instance is assigning itself to a new reference and another thread is reading (or worse assigning a different instance to it) the behavior would appear to be unpredictable. After reading quite a few articles on designing thread safety, I think I have an idea of how to approach it, but I do have a few questions to clear up first.
For example, I know that static methods are shared between all instances, but, are any instance variables created within the method shared also are does each invocation have its own copy? for example:
Code:
static MiniBI^ ModPow(MiniBI^ _base, MiniBI^ _exponent, MiniBI^ _modulus){
MiniBI^ _retval=gcnew MiniBI(); //would this variable be shared or would each invocation create its own instance?
.......rest of algorithm
return _retval;
}
Another question I have is about mutexes. If I create one mutex for the class and call WaitOne() when first entering the method would it allow the same thread to enter a different method within the same class? Example:
Code:
static MiniBI^ operator*(MiniBI^ _val1, MiniBI^ _val2){
_mymutex->WaitOne();
MiniBI^ _retval=gcnew MiniBI();
.....//guts of method
return _retval;
_mymutex->ReleaseMutex();
}
static MiniBI^ Pow(MiniBI^ _base, MiniBI^ _exponent){
_mymutex->WaitOne();
MiniBI^ _retval=gcnew MiniBI();
........
for(int x=0;x<_exponent->Length;x++){
_retval=_retval*_retval; //if this thread is in this method, will the operator* let this thread in to do its work
if(_exponent[x]==1){
_retval=_retval*_base; ///same with this one
}
}
return _retval;
_mymutex->ReleaseMutex();
}
So would the operator* method let the thread through since it allready has control of the mutex in the Pow method? would it still let it through if another thread had allready called WaitOne() in the operator* before it?
All of the operators are overloaded (and static) but, all of them convert the int to a MiniBI^ then call the version of the operator that handles only MiniBI^ values. Example:
Code:
static MiniBI^ operator+(MiniBI^ _val1, MiniBI^ _val2){
_mymutex->WaitOne();
MiniBI^ _retval=gcnew MiniBI();
.....guts of routine
return _retval;
_mymutex->ReleaseMutex();
}
static MiniBI^ operator+(MiniBI^ _val1, int _val2){
MiniBI^ _temp=gcnew MiniBI(_val2);
return _val1+_temp;
}
would the above work correctly? If I have the mutexes only in the methods that return a new reference do I need to use the mutex in the parts that just return a part of the current reference? (in other words read from it). I have been running these classes in simple multithreaded instances without trouble so far, but I have been playing around with vs 2010 and it is pushing them harder, even though I have not been able to point any problems to my classes yet, they do not appear to be thread safe from what I unbderstand so far.
Thanks in advance,
Richard
Last edited by AKRichard; August 13th, 2011 at 03:35 PM.
Reason: didnt mean to post it yet
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|