void foo ( Bar* bar , void(Bar::*qux)(void) )
{
if ( bar )
{
bar->qux();
}
}
The problem is:
bar
can be deleted after the check by another thread.
I can not add a mutex member to Bar
in order to lock it.
Thus I wonder, if I can tell the processor to run this function atomically, and how would I do so? I've spent way to much time on Google, but found no understandable manuals...
P.S. Debian, gcc , Boost NOT allowed, C++11 IS allowed.
The concept of atomic methods doesnt exist in C++ like it does in Java, where you can define a method as synchronized. The closest you can get to that in C++ would be to create a ScopedMutex class as follows:
class ScopedMutex {
public:
ScopedMutex(pthread_mutex *m) : theMutex_(m) {pthread_mutex_lock(theMutex_);}
~ScopedMutex() { pthread_mutex_unlock(theMutex_); }
// Add appropriate copy constructors and operator=() to disallow mutex copy
// Or consider passing in a reference
private:
pthread_mutex *theMutex_;
};
Then use it like this in your function:
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
ScopedMutex m(&aMutex); // This mutex must be defined/initialized elsewhere
if ( bar )
{
bar->qux();
}
// The ScopedMutex goes out of scope when the function does,
// thus releasing the lock
}
But this wont do you any good unless you use the same mutex in every other method that uses the bar object.
Scoped Mutex are especially useful when you have a function with complicated logic where there are several return statements, so you dont have to manually unlock the mutex it will be unlocked when the function goes out of scope.
You probably want to use a smart pointer with shared ownership semantics (e.g. shared_ptr
, intrusive_ptr
) to make sure the object stays alive as long as you refer to it.
You want to temporarily share ownership of the object, in order to prevent another thread from deleting it. This is a job for shared_ptr
, using weak_ptr
to allow deletion when we don't need to access it:
void foo ( std::weak_ptr<Bar> weak_bar , void(Bar::*qux)(void) )
{
if (std::shared_ptr<Bar> bar = weak_bar.lock())
{
// We now share ownership of the object - it won't be deleted
bar->qux();
}
// We have released ownership - it can now be deleted
}
Of course, you still need synchronisation if multiple threads need to access the object; this only solves the problem of deletion specified in the question.
Sorry, but no. C++ doesn't have anything to support that. You don't necessarily need to add the mutex to Bar
, but to avoid it, you'll probably need a wrapper around Bar
, or something on that order.
I too have a requirement for executing 2 functions atomically in Thread-1.
Main Thread:
CMythread* pThread = GetThreadFromPool();
//allocate work to thread
pThread->ResumeThread();
Thread-1:
AddtoThreadPool(this);
SuspendThread(); //sleep infinitely unless awakened by Main Thread
Problem:
Main Thread can resume the thread in the pool before it is suspended
and Thread-1 (pool thread) can suspend itself infinitely.
Solution:
1. Execute the 2 functions in the Thread-1 atomically. No amount of protection will work.
2. Periodically check the thread pool to resume a suspended thread that was allocated work.
Thanks for your answers.
Ajay