-
Is this thread safe
Is this example thread safe ?
Can i call directly the class`s method from different threads ?
Code:
class someclass
{
void DoSomething();
SomeMutex Mutex;
.....
};
void someclass::DoSomething()
{
WaitForMutex(Mutex);
....
//do some operations with the class data
....
ReleaseMutex(Mutex);
}
Thanks :)
-
Yes, but the way it is written it is not exception-safe. But that's a different problem.
-
-
Uh, I would describe the example as potentially not thread-safe in addition to not being exception safe.
Technically, if two threads dereference the same pointer, those threads need to synchronise access to that pointer. And, invoking a non-static member function on a particular object (implicitly) dereferences the "this" pointer for that object, and that operation cannot be protected by using a member of the object itself.
In practice, you can probably get away with it (on a lot of machines) if the operation involves read-only access to the object, particularly its non-static members. A basic problem is that the behaviour of WaitForMutex() and ReleaseMutex() can involve write access to the mutex itself, which is a non-static member of your class ...... basically, using a mutex that is owned by the object to protect the object gives a chicken and egg situation.
-
You quite possibly don't need a mutex here, that might be overkill. A simple critical section or spinlock type of thing should do the trick. You might also be interested in InterlockedIncrement / InterlockedDecrement.
The only case where there is a potential non-threadsafe problem with what the OP is doing is, deletion from a thread at the same time as another thread is executing a method involving that object. Afterall, that's the only time when the 'this' pointer could ever 'change', or rather 'change to being invalid', in this case.
-
Which comes back to my point that it is potentially thread unsafe: an object cannot protect itself from code outside itself.
Critical sections and use of InterLockedXXX() are just different ways of achieving similar effects. They don't give any protection that can't be achieved with a mutex.
Also, compiler implementations vary a bit. I remember reading internal documentation for one compiler that implemented
Code:
object->virtual_function()
by copying the address of object into a register, modifying that register by some offset, and then calling the virtual function, and discard the value in that register. That sort of thing is invisible to C++ code, but would give interesting effects in a multithreaded situation if two threads attempted the same series of operations.