How do I put a thread in a C++ smart pointer? - c++

I want to create a C++ class with a thread doing some work once a minute.
First, may I define a thread as a variable member?
class my_class
{
public:
my_class()
: my_thread_(task, this)
{
}
~my_class()
{
done_ = true;
}
void run()
{
while(!done_)
{
...do work in the thread...
}
}
private:
static task(my_class * ptr)
{
ptr->run();
}
std::thread my_thread_;
std::atomic<bool> done_ = false;
};
Second, may I instead use a smart pointer with the thread in it?
class my_class
{
public:
~my_class()
{
done_ = true;
}
void init()
{
my_thread_.reset(new std::thread(task, this));
}
void run()
{
while(!done_)
{
...do work in the thread...
}
}
private:
static task(my_class * ptr)
{
ptr->run();
}
std::unique_ptr<std::thread> my_thread_;
std::atomic<bool> done_ = false;
};
It seems to me that I need to join with the child thread before it can be destroyed, but I am wondering whether the destructor of std::thread knows to do that safely.

You can put std::threads where ever you want, they are not special. Destroying thread handles is problematic. You can implicitly detach, implicitly kill or implicitly join and every option is bad. std::~thread (usually) just kills the whole program. To prevent that join or detach it.
Since you seem to want to implicitly join you may want to use std::async (probably with the std::launch::async policy) to launch your threads. It returns an std::future who's destructor implicitly joins.

it's possible to create std::unique_ptr<std::thread>. It will call std::thread destructor, when scope of unique_ptr will end. Remember that calling std::thread destructor is not terminating running thready gently, but by std::terminate. To end std::thread normally, you have to run .join() on std::thread object.

According to cppreference.com,
A thread object does not have an associated thread (and is safe to
destroy) after
it was default-constructed
it was moved from
join() has been called
detach() has been called
So if you define the thread as a member variable and write your destructor like this:
~my_class()
{
done_ = true;
my_thread_.join();
}
everything is fine, because it is guaranteed by the standard that the std::thread destructor will be called only after the my_class destructor, see this Q/A.

Related

C++ std::shared_ptr custom deleter thread safety

[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).

Is it safe to use a boost::signals2::scoped_connection object as member of a class for automatic connection lifetime?

I wondered whether the following code is safe with respect to the fact that the signal might be triggered by a different thread:
using IntSignal = boost::signals2::signal<void(int)>;
class Foo
{
public:
Foo(IntSignal& signal)
: some_resource(new int(0))
{
scoped_connection = signal.connect([this](int i) { some_action(i); });
}
~Foo()
{
delete some_resource;
}
private:
void some_action(int i)
{
*some_resource = i;
}
int* some_resource;
boost::signals2::scoped_connection scoped_connection;
}
EDIT: added an imaginary resource, destructor and an implementation for some_action to make it more clear. With this question I would like to clarify whether my assumption is correct that the signal's slot might be called after Foo's destructor but before scoped_connection's destructor. I omitted a mutex protecting some_resource for brevity, however, it is not relevant for the question.
Although the connection will be dropped when a Foo instance is destroyed, there might be a tiny gap betwen Foo's own destructor invocation and the destruction of Foo's members. This might be even more problematic if resources are being used within some_action after they have been destructed.
Should I rather use normal connections and disconnect them in Foo's destructor? And would it be safe to have the scoped_connection member as last member of the class (that should get destroyed first) and omit any destruction logic?
You are right, there is a possible race if Foo's destructor is invoked while the signal is running and accessing some_resource.
A safe solution would be to extend the life of Foo while the slots are running:
class Foo : public std::enable_shared_from_this<Foo>
{
public:
Foo(IntSignal& signal)
: some_resource(new int(0))
{
// moved connection initialization to a method since weak_from_this will
// be empty inside the constructor. It is initialized only afterwards.
// It also make sense to connect your signal only after object
// is fully initialized
}
void InitConnection()
{
auto weak_self = weak_from_this();
scoped_connection = signal.connect(
[weak_self](int i)
{
if (auto self = weak_self.lock())
{
// we managed to promote weak_self to a shared_ptr, 'this' will be alive
// as long as this scope lives
some_action(i); // safe
}
});
}
~Foo()
{
// will only be invoked after Foo's reference count drops to zero.
// not during the signal is emitted
delete some_resource;
}
private:
void some_action(int i)
{
*some_resource = i;
}
int* some_resource;
boost::signals2::scoped_connection scoped_connection;
}
Notes:
enable_shared_from_this initializes a weak_ptr to 'this'. It is a great tool for the situation you described. See more here.
Make sure you create Foo as a shared_ptr, otherwise weak_from_this will not work.
Remember: Foo is shared between 2 threads.

c++ std::thread on stack

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.

Running a thread in a c++ class

I wish to create a class that has its own running thread. I have the following code to test kicking off a new thread.
class SingletonClass
{
public:
SingletonClass();
virtual ~SingletonClass(){};
static SingletonClass& Instance();
void DoSomething();
private:
static void MyThread(std::string data);
std::thread m_thread;
};
SingletonClass::SingletonClass()
{
m_thread = std::thread(MyThread, "test");
}
void SingletonClass::MyThread(std::string data)
{
while(1)
{
std::cout<<data<<std::endl;
}
}
void SingletonClass::DoSomething()
{
std::cout<<"Hello"<<std::endl;
}
SingletonClass& SingletonClass::Instance()
{
static SingletonClass _instance;
return _instance;
}
int _tmain(int argc, _TCHAR* argv[])
{
SingletonClass& singleton = SingletonClass::Instance();
singleton.DoSomething();
return 0;
}
When I run my program the thread function is called and then the program just bombs out with this error:
Why is this so? And how can I get the thread to keep running as long as the class is instantiated
EDIT
I have added in the thread object as a private variable and kicked it off in the constructor. It now doesnt crash.
This is what std::thread's destructor does (§30.3.1.3 [thread.thread.destr]):
~thread();
If joinable(), calls std::terminate(). Otherwise, has no
effects. [ Note: Either implicitly detaching or joining a joinable()
thread in its destructor could result in difficult to debug
correctness (for detach) or performance (for join) bugs encountered
only when an exception is raised. Thus the programmer must ensure that
the destructor is never executed while the thread is still joinable.
—end note ]
The local thread created in the SingletonClass constructor is destroyed when that constructor exits, causing terminate() to be called (which in turn calls abort() by default).
A possible fix is to make thread a member of the Singleton class, and join it in the destructor of Singleton (obviously if you do this you'd need some way to signal the thread to exit). Alternatively, you can consider detach()ing the thread in Singleton's constructor.

Singleton Synchronization C++

If I have to write a singleton class in C++ I will be using a static variable, private constructor & a public static function that returns an object of class. However in Multithreaded environments the code will have problems. In order to avoid multiple threads access the same variable at the same time, is Boost threads best mechanism to use for synchronization? I mean for setting/unsetting a lock/mutex across the resource. Is there anything else inbuilt in C++ standard library where in I dont have to download boost, build stuff etc? I have heard of C++ Ox but dont know much.
C++98/03 have nothing to support threads at all. If you're using a C++98 or 03 compiler, you're pretty much stuck with using Boost, or something (more or less) OS-specific, such as pthreads or Win32's threading primitives.
C++11 has a reasonably complete thread support library, with mutexes, locks, thread-local storage, etc.
I feel obliged to point out, however, that it may be better to back up and do a bit more thinking about whether you need/want a Singleton at all. To put it nicely, the singleton pattern has fallen out of favor to a large degree.
Edit: Rereading this, I kind of skipped over one thing I'd intended to say: at least when I've used them, any/all singletons were fully initialized before any secondary thread was started. That renders concern over thread safety in their initialization completely moot. I suppose there could be a singleton that you can't initialize before you start up secondary threads so you'd need to deal with this, but at least right off it strikes me as a rather unusual exception that I'd deal with only when/if absolutely necessary.
For me the best way to implement a singleton using c++11 is:
class Singleton
{
public:
static Singleton & Instance()
{
// Since it's a static variable, if the class has already been created,
// It won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods
protected:
Singleton()
{
// Constructor code goes here.
}
~Singleton()
{
// Destructor code goes here.
}
// And any other protected methods.
}
This is a c++11 feature but with this way you can create a thread safe Singleton. According to new standard there is no need to care about this problem any more. Object initialization will be made only by one thread, other threads will wait till it complete. Or you can use std::call_once.
If you want to make a exclusive access to the singleton's resources you have to use a lock at these functions.
The different type of locks:
Using atomic_flg_lck:
class SLock
{
public:
void lock()
{
while (lck.test_and_set(std::memory_order_acquire));
}
void unlock()
{
lck.clear(std::memory_order_release);
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck.clear();
}
private:
std::atomic_flag lck;// = ATOMIC_FLAG_INIT;
};
Using atomic:
class SLock
{
public:
void lock()
{
while (lck.exchange(true));
}
void unlock()
{
lck = true;
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck = false;
}
private:
std::atomic<bool> lck;
};
Using mutex:
class SLock
{
public:
void lock()
{
lck.lock();
}
void unlock()
{
lck.unlock();
}
private:
std::mutex lck;
};
Just for Windows:
class SLock
{
public:
void lock()
{
EnterCriticalSection(&g_crit_sec);
}
void unlock()
{
LeaveCriticalSection(&g_crit_sec);
}
SLock(){
InitializeCriticalSectionAndSpinCount(&g_crit_sec, 0x80000400);
}
private:
CRITICAL_SECTION g_crit_sec;
};
The atomic and and atomic_flg_lck keep the thread in a spin count. Mutex just sleeps the thread. If the wait time is too long maybe is better sleep the thread. The last one "CRITICAL_SECTION" keeps the thread in a spin count until a time is consumed, then the thread goes to sleep.
How to use these critical sections?
unique_ptr<SLock> raiilock(new SLock());
class Smartlock{
public:
Smartlock(){ raiilock->lock(); }
~Smartlock(){ raiilock->unlock(); }
};
Using the raii idiom. The constructor to lock the critical section and the destructor to unlock it.
Example
class Singleton {
void syncronithedFunction(){
Smartlock lock;
//.....
}
}
This implementation is thread safe and exception safe because the variable lock is saved in the stack so when the function scope is ended (end of function or an exception) the destructor will be called.
I hope that you find this helpful.
Thanks!!