Can this concept work?
class MyClass
{
public:
~MyClass()
{
MyMutex.acquire();
}
void ThreadFunction(void* param)
{
MyMutex.acquire();
//do something
MyMutex.release();
}
};
Also Let's say we have an object of this class, call it "inst"
What I am trying to achieve is that if:
One thread is active and executes inst->ThreadFunction
Another Thread is calling delete inst then this call will hang until ThreadFunction releases the mutex.
Is that ok to do?
It would be much better to create a wrapper around MyClass if MyClass contains resources. Its even worse if the program uses a class that inherits from MyClass, because the destructor for ChildofMyClass will have already been called by this point.
Related
[edited with a more concrete example]
Suppose I have a thread-safe object (all public member use a mutex) and a shared_ptr with a custom deleter, like so:
class A {
public:
void update(int x);
void print_sum();
...
}
class AContainer {
private SomeConcurrentMap<string, shared_ptr<A>> aMap;
void newA(string name) {
aMap.emplace(name, shared_ptr<A>(new A, [](A *p){p->print_sum(); delete p;}));
}
void finalizeA(string name) {
aMap.erase(name);
}
shared_ptr<A> getA(string name) const {
// fixme handle case of not found...
return aMap.find(name).second;
}
};
void someFunctionInSomeThread(const AContainer &cont, string name, int c) {
// fixme handle case of not found...
cont.getA(name)->update(c);
}
Let's assume all A operation are protected by a mutex, and that SomeConcurrentMap is thread-safe. The usage is scenario is:
call AContainer::newA() from any thread
call someFunctionInSomeThread() multiple times by multiple threads
call AContainer::finalizeA() from any thread - possibly in parallel to step 2
And the idea that A::print_sum() is called after both step 3 completed and all running A::update() operations complete.
Is it safe to assume that by the time p->print_sum() is called, all the A::update() operations on the object have been called?
Is it safe to assume that by the time p->print_sum() is called, all the A::update() operations on the object have been called?
Yes, it is safe to assume that. Only one thread is going to call the destructor, and no thread is going to call the destructor before calling other member functions of A (such a thread would be invoking UB even if no other threads existed, e.g. by keeping a raw pointer after destroying the shared pointer and then accessing the object via the raw pointer).
Assume I have class A with resource B. Class A has a function that does not acquire a mutex lock before I want to destroy it. I call boost::shared_ptr::reset() to destroy instance of class A. Is resource B guaranteed to be destroyed at that point?
class Resource{
public:
Resource(){ }
~Resource(){ free(); }
void init() {}
void free() {}
};
class A{
public:
A(){ B.init(); }
~A(){}
void functionC(){
boost::lock_guard<boost::mutex> lock(Mutex);
// Stuck forever
boost::lock_guard<boost::mutex> lock2(Mutex);
}
private:
boost::mutex Mutex;
Resource B;
};
main(){
boost::shared_ptr<A> pointer(new A());
// Do a function call that gets stuck but allows main thread to continue
boost::thread t(boost::bind(&A::functionC, *pointer));
pointer.reset();
// Loop forever
while(1);
}
To be specific, I want function B::free() to be called at the point in which I call pointer.reset(). Is this code guaranteed to do that, or do I have to explicitly call it somewhere? Obviously I don't want to be as explicit as
pointer->freeB();
pointer.reset();
In your scenario, B is a member of A. It will get destroyed (and free() will be called) when A gets destroyed. No need for an explicit call.
However in your code, there's no guarantee that your pointer.reset() the allocated A object gets destroyed: it only gets destroyed if pointer was the only shared_ptr pointing to this object, i.e. no copy of the pointer was made since its creation (there 's no evidence of that here, but to be checked in your real code).
By the way, there's a t.join() missing in your code.
I know this is very silly question about singleton pattern but still it is first choice of interviewer.
Could you let me know in below code snippet.
(1) After deleting singleton object why still I am able to call show() method and it works fine.
delete obj;
obj=NULL;
obj->show();
(2) After creating obj1 object why i am not able to print the content of acquire_lock and release_lock function even print statment "one Time" will be printed once and if we increment counter i then instead of 2 it is printing 1 only, why?
Foo *obj1=MySingleton<Foo>::GetInstance();
(3) usage of unique_ptr with singleton object will have any negative implications.
code snippet:
#include <iostream>
#include <fstream>
#include <memory>
#include <string>
using namespace std;
static int i;
class Lock
{
public:
Lock(){};
~Lock(){};
void acquire_lock()
{
cout<<"aquired lock for class";
}
void release_lock()
{
cout<<"released lock for class";
}
};
class Foo
{
public:
void show()
{
cout<<"\ndone\n";
}
};
template <class T>
class MySingleton
{
protected:
MySingleton() {}
private:
//holds one and only object of MySingleton
static T* m_pOnlyOneInstance;
MySingleton(const MySingleton <T> &) {};
MySingleton <T> & operator=(const MySingleton <T> &) {};
~MySingleton() {};
public:
static T * GetInstance();
void foo()
{
cout<<"Mohan";
}
};
template <class T>
T* MySingleton<T>::GetInstance()
{
Lock lock;
if (m_pOnlyOneInstance == NULL)
{
lock.acquire_lock();
cout<<"one Time"<<endl;
i++;
if(m_pOnlyOneInstance == NULL)
{
m_pOnlyOneInstance = new T();
}
lock.release_lock();
}
return m_pOnlyOneInstance;
}
template <class T> T* MySingleton<T> :: m_pOnlyOneInstance=NULL;
int main()
{
//std::unique_ptr <Foo> obj (MySingleton<Foo>::GetInstance());
Foo *obj=MySingleton<Foo>::GetInstance();
//obj->show();
delete obj;
obj=NULL;
obj->show();
cout<<"\ncalling again\n";
Foo *obj1=MySingleton<Foo>::GetInstance();
obj1->show();
cout<<"i="<<i;
return 1;
}
Note: lock related function are dummy implementation only.
Keep in mind that obj->show() is equivalent to Foo::show(obj). Both expressions set this to the value of obj within the show member function. Now, what would setting this to NULL within show do? Nothing, because you never reference this.
Well, think about the whole reason you would use the singleton pattern in the first place -- to initialize something at most one time. That "one time" print statement is in the code where the object gets instantiated, so naturally it doesn't get executed after the first time. Look at the logic of GetInstance. If an instance does not exist, it instantiates the class (messily... but it does work), and afterwards the instance exists. Otherwise, it does nothing.
This question is very unclear, but what I assume you mean is "what are the negative implications of doing std::unique_ptr<Foo> obj = MySingleton<Foo>::GetInstance();?" As you can see from the reference for unique_ptr, its purpose is to take ownership of a dynamically allocated resource. This is definitely not supposed to happen when you're dealing with singleton objects. Because the resource (the singleton instance, in this case) is shared among any number of callers, the singleton class is the only one which should be managing the instance resource -- this is a fundamental invariant of the singleton pattern. If you use unique_ptr, as soon as obj goes out of scope, it will delete the instance automatically, regardless of whether your program references the now-freed instance elsewhere.
This is not a proper way to delete the singleton object, you need to write below method in order to delete the instance and then execute your programme.
static void cleanup()
{
delete m_pOnlyOneInstance;
m_pOnlyOneInstance= NULL;
}
Here is the output :
aquired lock for classone Time
released lock for class
done
calling again
aquired lock for classone Time
released lock for class
done
i=2
(1)
The call would fail if it actually used obj either to perform the call or within the call.
First the call it self is to a non virtual function so the obj pointer is not needed to find the function. The compiler already figured out at compile time which function to call.
Second the function does not access any member variables of the class so while it does receive a this pointer that is NULL it actually never uses it.
BTW, it seems that this code tries to use the MySingleton template to turn other classes into singletons but it doesn't really as it doesn't prevent making copies or instantiating objects through other ways so it is no true singleton. The only thing it does is always return the same pointer.
Other BTW, the second call to MySingleton<Foo>::GetInstance() returns a copy of a pointer that you have previously deleted when you did delete obj. obj was set to NULL after the delete but the original pointer in the MySingleton template is still pointing to the deleted object so the second call to GetInstance will happily return the now invalid pointer.
Your singleton class should have a private constructor and destructor. The destructor should handle any memory cleanup when the scope of the singleton ends, so there's no need to explicitly delete it. It could be unsafe to delete it when other objects are still accessing the singleton after the point of deletion. You could be getting an undefined behavior when you did "delete obj", and "obj=null" since you overloaded assignment operator and destructor are private.
I have an object with a normal constructor. The constructor has a lot of initialization to do. Much of this initialization can be performed asynchronously, so I am calling a new thread from within the constructor.
When the thread in initialized on the stack, it appears that the thread is destroyed when the constructor exits which causes a crash. This would look like so:
class MyObject
{
MyObject()
{
// Typical initialization
// ...
// Time consuming initialization
std::thread(&MyObject::Init; this); // Create new thread to call Init();
// Crash when exit MyObject() here
}
void Init()
{
// Time consuming operations
}
};
The alternative (which works) is to create the thread on the heap as such.
class MyObject
{
std::thread* StartupThread;
MyObject()
{
// Typical initialization
// ...
// Time consuming initialization
StartupThread = new std::thread(&MyObject::Init; this); // Create new thread to call Init();
// Crash when exit MyObject() here
}
~MyObject()
{
StartupThread->join();
delete StartupThread;
}
void Init()
{
// Time consuming operations
}
};
My Question
Is there any harm is leaving the unjoined & undisposed thread object alive for the lifetime of the object or should I try to clean it up as soon as Init() finishes?
Is there a way to "automatically" dispose the thread when it finishes so it isn't left hanging around?
Essentially, can I get the thread on the stack in some way without it crashing as I described?
What about:
class MyObject
{
MyObject ()
{
f = std::async (std::launch::async, &MyObject::Init, this);
}
private:
void Init ();
std::future<void> f;
};
This allows you to do f.get () when you want to synchronize on the task. The destructor will join automatically if it is the last living copy of the object (you may want to delete the copy constructor if you don't want this behavior).
Note that you want to synchronize at some point before destruction, since if Init throws an exception, your destructor will.
Also, see this if you want to go the detach route.
You can call std::thread::detach() from the stack, but this is very dangerous considering the object could be long deleted while it's still running.
According to your requirements, the best option is to make sure it joins at the end of both Init() and the de-constructor. I think the better design is to join() at the end of the constructor for simplicity. Assuming there's no other processing to be done once you start the thread and when Init() is invoked, this would be the best choice.
Currently I want to make wrapper accessor class in multithreaded environment. The purpose of the class is simple - Grab a lock on its construction and release a lock on its destruction. Other than that, it's identical to a normal pointer. Moreover, I want to prevent it from being created on heap area to ensure that the lock will be released eventually.
The inverse is fairly easy (private constructor with factory method), but I don't know that a stack-only variable is possible. Is there anyway?
Well, what about you overload operator new for your class and delcare it private?
I don't understand the problem? Any variable defined within the scope of a function is stack-only.
class Lock {
public:
Lock() {
performLock();
}
~Lock() {
performUnlock();
}
}
void foo() {
// ... Code
Lock onStackOnly;
// ... Code that is locked
}
void foo() {
// ... Code
{
Lock onStackOnly;
// ... Code that is locked
}
// This code is unlocked.
}