Threading member function of multiple objects - c++

I've got 2 class' where in the constructor of each spawns a thread which just prints hello world or goodbye universe. My goal is for the program to print out both hello world and goodbye universe at the same time. Problem is the program currently waits for the first thread to finish before starting the second. Its basically thread 1 is blocking the creation of threa2 until it finishes. What is the correct way for both threads to be executing at the same time?
My code is
#include <iostream>
#include "voltage.h"
#include <thread>
class MyClass final
{
private:
std::thread mythread;
void _ThreadMain()
{
int x = 1000;
while(x>0)
{
std::cout << "hello world " << x << std::endl;
x--;
}
};
public:
MyClass()
: mythread{}
{
mythread = std::thread{&MyClass::_ThreadMain, this};
mythread.join();
}
};
class MyClass2 final
{
private:
std::thread mythread;
void _ThreadMain()
{
int x = 1000;
while(x>0)
{
std::cout << "goodbye universe " << x << std::endl;
x--;
}
};
public:
MyClass2()
: mythread{}
{
mythread = std::thread{&MyClass2::_ThreadMain, this};
mythread.join();
}
};
int main(int argc, char *argv[])
{
MyClass *myClass = new MyClass();
MyClass2 *myClass2 = new MyClass2();
return 0;
}
My compile arguments are
g++ -g -march=armv6 -marm -I Sources/ main.cpp -L libraries/ -lyocto-static -lm -lpthread -lusb-1.0
Most of that is for other parts of the program i'm working on

Start threads in constructors and call join methods in destructors of your classes:
MyClass()
: mythread{} {
mythread = std::thread{&MyClass::_ThreadMain, this};
}
~MyClass() {
mythread.join();
}
MyClass2()
: mythread{} {
mythread = std::thread{&MyClass2::_ThreadMain, this};
}
~MyClass2() {
mythread.join();
}
but then you need to add in main the following lines
delete myClass; // wait until thread started in myClass ends
delete myClass2; // wait until thread started in muClass2 ends
to force destructors to be called.

Related

How do I make a seperate thread inside a class?

I have a class foo and i put inside a member function a thread object. And i tried to initialize it like this std::thread mythread(&foo::myprint, this); inside another function. My problem is that I get the same thread::get_id with a different function foo::mycount that i need to count something. Both myprint and mycount uses this_thread::sleep_for but they don't sleep separately (something that i want to happen). I follow you up with some code example
class foo
{
void func()
{
std::thread mythread(&foo::myprint, this);
mythread.join();
}
void myprint()
{
sleep_for(1s);
cout << count << endl;
}
void mycount()
{
sleep_for(1ms);
count++;
cout << count << endl;
}
};
void main()
{
foo obj;
while(1)
{
obj.func();
obj.mycount();
}
}
I also tried putting mycount in another function with a thread object, and I don't if std::call_once affected anything, cause i used it inside the mycount function. I expected a different get_id for different functions.
Here is an example with a lambda function to start an asynchronous process.
And using std::future for synchronizing the destructor of your class with the background thread (which is counting numbers in this example).
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
// dont do "using namespace std"
using namespace std::chrono_literals;
class foo
{
public:
foo() = default;
~foo()
{
// destructor of m_future will synchronize destruction with execution of the thread (waits for it to finish)
}
void func()
{
m_future = std::async(std::launch::async, [=] { myprint(); });
}
void myprint()
{
for (std::size_t n = 0; n < 5; ++n)
{
std::this_thread::sleep_for(1s);
std::cout << n << " ";
}
std::cout << "\n";
}
private:
std::future<void> m_future;
};
int main()
{
foo obj;
obj.func(); // start thread
return 0;
}

Cannon run an overridden method

There is a class "Mario". This one has an virtual method: void mission(). I want override this method and run it from base class code in parallel.
But output of the following code is:
Mario works hard
LOL
Code:
#include <iostream>
#include <thread>
class Mario
{
std::thread workingField;
bool hasStarted = false;
public:
virtual void mission()
{
std::cout << "LOL" << std::endl;
}
void startMission()
{
if (!hasStarted)
{
workingField = std::thread([this]() {
this->mission();
});
hasStarted = true;
}
}
virtual ~Mario()
{
if (hasStarted)
{
workingField.join();
}
}
};
class MarioWorker : public Mario
{
public:
void mission() override final
{
std::cout << "Mario works hard" << std::endl;
}
};
int main(int argc, char *argv[])
{
MarioWorker mw;
mw.mission();
mw.startMission();
}
How can I get a double line "Mario works hard", when one of them is executed in another thread?
In other words how a base class can execute an overridden method in parallel?
I'm using GCC 9.3
The problem is, the main thread is too fast. Your main method ends, the deconstruction of mw starts, MarioWorker gets destructed and once it starts destructing the Mario it joins the thread. The thread never sees the MarioWorker as it was already destructed, all it sees is the Mario.

Thread inside a class with member function from another class

Can someone tell me how can I run a new thread with member function from a object of diffrent class as a member function of this class ? What ever im trying to do Im still getting errors.
no match for call to '(std::thread) (void (Boo::*)(), Boo&)'|
no match for call to '(std::thread) (void (Foo::*)(), Foo*)'|
#include <iostream>
#include <thread>
using namespace std;
class Boo
{
public:
void run()
{
while(1){}
}
};
class Foo
{
public:
void run()
{
t1(&Boo::run,boo);
t2(&Foo::user,this);
}
void user();
~Foo(){
t1.join();
t2.join();
}
private:
std::thread t1;
std::thread t2;
Boo boo;
};
int main()
{
Foo foo;
foo.run();
}
You need to use operator= to assign the threads after construction
Working example below (see it in action):
#include <thread>
#include <iostream>
class Boo
{
public:
void run()
{
int i = 10;
while(i--)
{
std::cout << "boo\n";;
}
}
};
class Foo
{
public:
void run()
{
t1 = std::thread(&Boo::run,boo); // threads already default constructed
t2 = std::thread(&Foo::user,this); // so need to *assign* them
}
void user()
{
int i = 10;
while(i--)
{
std::cout << "foo\n";;
}
}
~Foo()
{
t1.join();
t2.join();
}
private:
std::thread t1;
std::thread t2;
Boo boo;
};
int main()
{
Foo foo;
foo.run();
}

c++ meyers singleton containing std::thread can't join

i have a problem with the scott meyers singleton. my singleton contains a thread which shall get joined in the singleton destructor, but the join() never returns.
When i join the thread before application exit everything works fine. am i missing something? following my code:
#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>
class Singleton
{
public:
static Singleton& get_instance()
{
static Singleton instance;
return instance;
}
void stop()
{
run = false;
if (t.joinable())
t.join();
}
private:
Singleton() { t = std::thread{ &Singleton::f, this }; }
~Singleton()
{
std::cout << "dtor start" << std::endl;
stop();
std::cout << "dtor end" << std::endl; // <-- never gets called. programm freezes here
}
void f()
{
while (run)
{
// do work ...
std::cout << "i do some work..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
std::atomic<bool> run = true;
std::thread t;
};
int _tmain(int argc, _TCHAR* argv[])
{
auto& s = Singleton::get_instance();
std::this_thread::sleep_for(std::chrono::seconds(2));
s.stop(); // <-- works fine
return 0;
}
So as i mentioned: with the call to s.stop(); it works fine but without it "freezes".
Is there a way to prevent the call to stop() ?

How can I access my class instance from a boost thread?

I have the following code (this is some semi-sudo code, which may not compile):
class FooBar {
public:
void a();
void b();
boost::shared_ptr<boost::thread> m_thread;
std::string m_test;
};
void FooBar::a() {
m_test = "Foo bar"
m_thread = shared_ptr<thread>(new thread(bind(&FooBar::b, this)));
}
void FooBar::b() {
cout << m_test;
}
The code cout << test does not yield any output, because m_test is "" instead of "Foo bar". Why is this? I thought that passing this as the 2nd argument to bind would allow me to access the same instance from b() - am I incorrect?
Yes, that works. Here's the "real" version, which does in fact print "Foo bar":
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
using namespace boost;
struct FooBar {
void a();
void b();
shared_ptr<thread> m_thread;
std::string m_test;
};
void FooBar::a() {
m_test = "Foo bar";
m_thread = make_shared<thread>(bind(&FooBar::b, this));
}
void FooBar::b() {
std::cout << m_test;
}
int main() {
FooBar fb;
fb.a();
fb.m_thread->join();
return 0;
}
The code cout << test does not yield any output, because m_test is ""
I suspect this is because the object was being destroyed before the thread got around to evaluating the member variable. Note the join(), it's very important.