Moving std::thread and maintaining state - c++

I have a class which maintains a worker thread. It needs to be move constructible as I pass them around and add/remove from arrays, such as:
for (...) {
Foo foo;
foos.push_back(std::move(foo));
}
The class setup looks like this:
Foo::Foo() : worker(), working(true) {
worker = std::thread(&Foo::work, this);
}
Foo::Foo(Foo &&foo) {
working = true;
worker = std::move(foo.worker);
}
Foo::~Foo() {
if (worker.joinable()) {
working = false;
worker.join();
}
}
void Foo::work() {
while(working) {
std::cout << "working..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
The problem is that after a Foo has been moved, its worker thread exits. I discovered it's because working is now seen by the worker to be false.
How can I get the worker thread to see the instance variables of the new (moved-to) parent Foo object? Is this possible? Is my move constructor totally wrong?

Related

Custom std::thread that ends only on signal

I already asked this question in another post, but it came out poorly, so I want to rephrase it better.
I have to start a series of threads doing different tasks, that only have to return if an exit signal was sent, otherwise (if they incur in exceptions or anything else) they just restart their code from beginning.
To make my intent clear, here's some code:
class thread_wrapper
{
public:
template<typename _Callable, typename... _Args>
thread_wrapper();
void signal_exit() {exit_requested_ = true;}
void join() {th_.join();}
private:
std::thread th_;
bool exit_requested_{false};
void execute()
{
while(!exit_requested_)
{
try
{
// Do thread processing
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
return;
}
};
What I want to achieve, is to use this class as it was a normal std::thread, passing a function and its arguments when it is initialized, but then I want the inner std::thread to run the "execute" function, and only inside the try block I want it to run the behaviour passed in constructor.
How could I achieve this? Thanks in advance.
EDIT: I found a solution, but I am able to run only in c++ 17 (because of the template on lambda), and it is not really that elegant in my opinion.
template<typename Lambda>
class thread_wrapper
{
public:
explicit thread_wrapper(Lambda&& lambda) : lambda_{std::move(lambda)}, th_(&thread_wrapper::execute, this){};
void signal_exit() {exit_requested_ = true;}
void join() {th_.join();}
private:
std::thread th_;
bool exit_requested_{false};
Lambda lambda_;
void execute()
{
while(!exit_requested_)
{
try
{
lambda_();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
return;
}
};
And here is a sample main:
class Foo
{
public:
void say_hello() { std::cout << "Hello!" << std::endl;}
};
int main()
{
Foo foo;
thread_wrapper th([&foo](){foo.say_hello(); std::this_thread::sleep_for(2s);});
std::this_thread::sleep_for(10s);
th.signal_exit();
th.join();
}
What do you think?
I'd say the solution you found is fine. You might want to avoid the thread_wrapper itself being a templated class and only template the constructor:
// no template
class thread_wrapper {
public:
template<typename Lambda, typename... Args>
explicit thread_wrapper(Lambda lambda, Args&&... args) {
:lambda_(std::bind(lambda, std::forward<Args>(args)...))
}
// ...
private:
std::function<void()> lambda_;
// ...
};
(I didn't try to compile this - small syntax errors etc are to be expected. It's more to show the concept)
Important: if you do call signal_exit, it will not abort the execution of lambda_. It will only exit once the lambda has returned/thrown.
Two little naming things to consider:
thread_wrapper is not a great name. It doesn't tell us anything about the purpose, or what it does different than a regular thread. Maybe robust_thread (to signify the automatic exception recovery) or something.
The method signal_exit could just be named exit. There is no reason to make the interface of this class specific to signals. You could use this class for any thread that should auto-restart until it is told to stop by some other part of the code.
Edit: One more thing I forgot, exit_requested_ must be either atomic or protected by a mutex to protect from undefined behavior. I'd suggest an std::atomic<bool>, that should be enough in your case.
I would use std::async and a condition variable construction for this.
I wrapped all the condition variable logic in one class so it can easily be reused.
More info on condition variables here : https://www.modernescpp.com/index.php/c-core-guidelines-be-aware-of-the-traps-of-condition-variables
Don't hesitate to ask for more information if you need it.
#include <chrono>
#include <future>
#include <condition_variable>
#include <mutex>
#include <iostream>
#include <thread>
//-----------------------------------------------------------------------------
// synchronization signal between two threads.
// by using a condition variable the waiting thread
// can even react with the "sleep" time of your example
class signal_t
{
public:
void set()
{
std::unique_lock<std::mutex> lock{m_mtx};
m_signalled = true;
// notify waiting threads that something worth waking up for has happened
m_cv.notify_all();
}
bool wait_for(const std::chrono::steady_clock::duration& duration)
{
std::unique_lock<std::mutex> lock{ m_mtx };
// condition variable wait is better then using sleep
// it can detect signal almost immediately
m_cv.wait_for(lock, duration, [this]
{
return m_signalled;
});
if ( m_signalled ) std::cout << "signal set detected\n";
return m_signalled;
}
private:
std::mutex m_mtx;
std::condition_variable m_cv;
bool m_signalled = false;
};
//-----------------------------------------------------------------------------
class Foo
{
public:
void say_hello() { std::cout << "Hello!" << std::endl; }
};
//-----------------------------------------------------------------------------
int main()
{
Foo foo;
signal_t stop_signal;
// no need to create a threadwrapper object
// all the logic fits within the lambda
// also std::async is a better abstraction then
// using std::thread. Through the future
// information on the asynchronous process can
// be fed back into the calling thread.
auto ft = std::async(std::launch::async, [&foo, &stop_signal]
{
while (!stop_signal.wait_for(std::chrono::seconds(2)))
{
foo.say_hello();
}
});
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "setting stop signal\n";
stop_signal.set();
std::cout << "stop signal set\n";
// synchronize with stopping of the asynchronous process.
ft.get();
std::cout << "async process stopped\n";
}

How to fix this shared_ptr reference cycles?

I designed an App that holds a stack of layers and an active obj.
When a Layer is attached to the App, the Layer tells App what an active object is. But my design causes a sigtrap when deallocating.
It cause sigtrap because the destruction of shared_ptr<Obj> m_obj in App happens first which reduce the use_count to 1. Then the onDetech function gets call, setting the active shared_ptr<Obj> m_obj to nullptr and reduce use_count to 0! But the layer still holds an shared_ptr<Obj>.
The code below is a minimal example to reproduce. I notice my code has a reference cycle but I have no idea how to fix this except using a raw pointer for obj in the App class.
I used shared_ptr for obj in App because it makes sense to me that App has the shared ownership of obj. Should I not use shared_ptr in this case?
class App;
class Obj {
public:
~Obj() { std::cout << "obj destruct" << std::endl; }
};
class Layer {
public:
Layer() { m_obj = std::make_shared<Obj>(); }
~Layer() { std::cout << m_obj.use_count() << std::endl; }
void onAttach(App *app);
void onDetach();
std::shared_ptr<Obj> m_obj;
private:
App *m_app;
};
class LayerStack {
public:
void pushLayer(App *app, std::shared_ptr<Layer> layer) {
m_layers.push_back(layer);
layer->onAttach(app);
}
~LayerStack() {
for (auto &layer : m_layers) {
layer->onDetach();
}
}
private:
std::vector<std::shared_ptr<Layer>> m_layers;
};
class App {
public:
App() {
m_defaultLayer = std::make_shared<Layer>();
m_stack.pushLayer(this, m_defaultLayer);
}
~App() {}
LayerStack m_stack;
std::shared_ptr<Layer> m_defaultLayer;
std::shared_ptr<Obj> m_activeObj;
};
void Layer::onAttach(App *app) {
m_app = app;
app->m_activeObj = m_obj;
std::cout << m_obj.use_count() << std::endl;
}
void Layer::onDetach() {
m_app->m_activeObj = nullptr;
std::cout << m_obj.use_count() << std::endl;
}
int main() {
A a;
}
output:
2
obj destruct
-923414512
-923414512
You're accessing m_activeObj after its lifetime has ended, and thus the behavior of your program is undefined.
The sequence of events is as follows:
App object goes out of scope
~App runs
m_activeObj is destroyed; after this its lifetime has ended and it can no longer be accessed
m_defaultLayer is destroyed
m_stack is destroyed
m_layers[0].onDetach() is called
onDetach sets m_app->m_activeObj to nullptr, but its lifetime has already ended, so behavior is undefined.
Irrelevant other stuff; you're already screwed.
The solution is to reorder things so that you don't access m_activeObj after its lifetime has ended. Either move m_stack's declaration after m_activeObj so it gets destroyed first or clear it manually in ~App.

C++ background thread in class - instance scope

I have this simple class:
struct Foo {
void Run() {
this->bgLoader = std::thread([this]() mutable {
//do something
this->onFinish_Thread();
});
}
std::function<void()> onFinish_Thread;
std::thread bgLoader;
};
That is called from C-API:
void CApiRunFoo(){
Foo foo;
foo.onFinish_Thread = []() {
//do something at thread end
};
foo.Run();
}
I want to run CApiRunFoo, return from it but keep the thread running until it is finished.
Now, the problem is, that once CApiRunFoo end, foo goes out of scope even if background thread is still running. If I change foo to object via new, it will run, but it will cause memory leak.
I was thinking to create destructor with:
~Foo(){
if (bgLoader.joinable()){
bgLoader.join();
}
}
but I am not sure if it can cause deadlock or not plus it probably wont cause CApiRunFoo to return until the thread finishes.
Is there any solution/design pattern to this problem?
You could return the Foo instance to the C program:
struct Foo {
~Foo() {
if (bgLoader.joinable()) {
run = false;
bgLoader.join();
}
}
void Run() {
run = true;
this->bgLoader = std::thread([this]() mutable {
while(run) {
// do stuff
}
this->onFinish_Thread();
});
}
std::atomic<bool> run;
std::function<void()> onFinish_Thread;
std::thread bgLoader;
};
The C interface:
extern "C" {
struct foo_t {
void* instance;
};
foo_t CApiRunFoo() {
Foo* ptr = new Foo;
ptr->onFinish_Thread = []() {
std::cout << "done\n";
};
ptr->Run();
return foo_t{ptr};
}
void CApiDestroyFoo(foo_t x) {
auto ptr = static_cast<Foo*>(x.instance);
delete ptr;
}
}
And a C program:
int main() {
foo_t x = CApiRunFoo();
CApiDestroyFoo(x);
}
Demo
As it seems you'd like the Foo objects to automatically self destruct when the thread finishes, you could run them detached and let them delete this; when done.
#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <iostream>
#include <functional>
#include <mutex>
#include <thread>
// Counting detached threads and making sure they are all finished before
// exiting the destructor. Used as a `static` member of `Foo`.
struct InstanceCounter {
~InstanceCounter() {
run = false;
std::unique_lock lock(mtx);
std::cout << "waiting for " << counter << std::endl;
while(counter) cv.wait(lock);
std::cout << "all done" << std::endl;
}
void operator++() {
std::lock_guard lock(mtx);
std::cout << "inc: " << ++counter << std::endl;
}
void operator--() {
std::lock_guard lock(mtx);
std::cout << "dec: " << --counter << std::endl;
cv.notify_one(); // if the destructor is waiting
}
std::atomic<bool> run{true};
std::mutex mtx;
std::condition_variable cv;
unsigned counter = 0;
};
struct Foo {
bool Run() {
try {
++ic; // increase number of threads in static counter
bgLoader = std::thread([this]() mutable {
while(ic.run) {
// do stuff
}
// if onFinish_Thread may throw - you may want to try-catch:
onFinish_Thread();
--ic; // decrease number of threads in static counter
delete this; // self destruct
});
bgLoader.detach();
return true; // thread started successfully
}
catch(const std::system_error& ex) {
// may actually happen if the system runs out of resources
--ic;
std::cout << ex.what() << ": ";
delete this;
return false; // thread not started
}
}
std::function<void()> onFinish_Thread;
private:
~Foo() { // private: Only allowed to self destruct
std::cout << "deleting myself" << std::endl;
}
std::thread bgLoader;
static InstanceCounter ic;
};
InstanceCounter Foo::ic{};
Now the C interface becomes more like what you had in the question.
#include <stdbool.h>
extern "C" {
bool CApiRunFoo() {
Foo* ptr = new Foo;
ptr->onFinish_Thread = []() {
std::cout << "done" << std::endl;
};
return ptr->Run();
// it looks like `ptr` is leaked here, but it self destructs later
}
}
Demo
Your program should call join and finish the new thread at some point in future (see also this question with answer). To do that, it should hold a reference (in a wide sense) to the thread object. In your current design, your foo is such a reference. So you are not allowed to lose it.
You should think about a place where it makes sense to do join in your code. This same place should hold your foo. If you do that, there is no problem, because foo contains also the onFinish_Thread object.

c++ Creating a new thread from a member function and moving the object and the entire

according to the code bellow, is myClass1 object and myClass2 obj (which is the myClass1 object's member ) moving to the new thread with their memory(Like std::move()) ?
class myClass1{
public:
myClass2 obj;
myClass1(myClass2 * obj) {
this.obj = *obj;
}
thread spawn() {
return std::thread([this] { this->Run(); });
}
void Run() {
cout << "new thread" << endl;
}
}
myClass2{
public :
string str;
MyClass2(string str){
this.str = str;
}
}
int main(){
myClass1 object(new myClass2("test"));
thread t = object.spawn();
t.join();
........
}
As it stands, your main will call std::terminate, because you discard a joinable std::thread.
If you join it, main will block until the thread has finished. object will remain alive for the entire duration of Run.
If you detach it, main may end before the thread does, object will cease to exist and the this in myClass1::Run will be invalid. Undefined Behaviour.
A tidy up of your code
class myClass1 {
myClass2 obj;
public:
// Take by rvalue, uses the move constructor for obj
myClass1(myClass2 && obj) : obj(obj) {}
std::thread spawn() {
return std::thread([this]
{
// This is suspicious, but safe
auto self = std::move(*this);
self.Run();
});
}
void Run() {
std::cout << "new thread" << std::endl;
}
}
int main(){
// new is not required
myClass1 object(myClass2("test"));
object.spawn().join();
/* other stuff, not involving object */
return 0;
}
Even more of a tidy up
class myClass1 {
myClass2 obj;
public:
// Take by rvalue, uses the move constructor for obj
myClass1(myClass2 && obj) : obj(obj) {}
void Run() {
std::cout << "new thread" << std::endl;
}
}
int main() {
// Just create the instance of myClass1 as a parameter to `std::thread`'s constructor
std::thread(&myClass1::Run, myClass1(myClass2("test"))).join();
/* other stuff */
return 0;
}
No; creating a thread does not magically make the thread take ownership of that memory. If you create an object on the stack, create a thread that uses it; and then unwind the stack, destroying the object; with the thread still running, you will have undefined behaviour.
If you want to give ownership of some data to the thread, the easiest way to do it is with a shared pointer.

C++11 Start new thread from class constructor and error

I saw on stackoverflow a few idea to start thread from class.
My func - this func have to be run
//header.h
private:
void updateTime();
//cpp
void class::updateTime(){
while (true){
Sleep(1000);
}
}
From my class constructor ( this is QT class constructor )
I try with that:
std::thread t1{&class::updateTime,this};
Or in lambda style
std::thread t1{ [this] { updateTime(); } };
But i still got a error
I thought that methods should work ;0 Debugger return this:
From the description in the comments, it sounds like you want your class to be somewhat like this:
struct foo
{
void updateTimer()
{
while(running_) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Hello" << std::endl;
}
}
std::atomic_bool running_{true};
std::thread t_{&foo::updateTimer, this};
~foo()
{
running_ = false;
t_.join();
std::cout << "Thread stopped\n";
}
};
The above class launches a thread upon construction, which prints Hello once every second until it is signaled to stop. This signaling is done by ~foo(), and this is necessary because without it, the destructor for t would execute while it is joinable. This would result in std::terminate being called. It is necessary that an std::thread that is joinable be either joined, or detached, to prevent this from happening.
Here's an example of the above class being used.