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.
Related
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";
}
In the book
"C++ Concurrency In Action" by Anthony Williams
you can find the following two snippet of code (I have introduced some slight modifications):
Snippet 1:
class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_): t(t_){}
~thread_guard()
{
if(t.joinable())
{
t.join();
}
}
thread_guard(thread_guard const&)=delete;
thread_guard& operator=(thread_guard const&)=delete;
};
void my_func()
{
for(int j = 0; j < 1000; ++j)
{
cout << "\n " << j;
}
}
void f()
{
std::thread t1(my_func);
thread_guard g(t1);
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
Going on you can find
Snippet 2:
class scoped_thread
{
std::thread t;
public:
explicit scoped_thread(std::thread t_): t(std::move(t_))
{
if(!t.joinable())
throw std::logic_error(“No thread”);
}
~scoped_thread()
{
t.join();
}
scoped_thread(scoped_thread const&)=delete;
scoped_thread& operator=(scoped_thread const&)=delete;
};
void my_func()
{
for(int j = 0; j < 1000; ++j)
{
cout << "\n " << j;
}
}
void f()
{
scoped_thread st1(thread(my_func));
thread t2(my_func);
scoped_thread st2(move(t2));
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
I'm not sure that I can really appreciate the real difference between these 2 snippets.
The only difference that I can see is that in Snippet 1 the instance of thread_guard does not take ownership of the thread t1 (unlike a scoped_thread object) and so it could be possible call t1.join() but this is not a problem when ~thread_guard() is executed.
So: where is (if exists) the advantage of Snippet 2?
Both types are meant to block on destruction (e.g. scope exit) until a thread finishes. The difference is in the ownership of the thread object.
thread_guard doesn't own the thread itself; there may be more than one thread_guard waiting on the same thread. This also means that the thread object must be alive as long as any thread_guard refers to it. If the referenced thread has already been joined when a thread_guard object is destroyed, it won't block or produce an error (as opposed to just calling join on a thread that is not joinable).
scoped_thread, on the other hand, takes ownership of the thread instance, and therefore also controls its lifetime. You would use it whenever you want to own the thread you want to wait on, e.g. as a data member.
Ultimately, which one you use is a question of semantics: do you want to wait on a thread someone else owns (then you also have to make sure there are no lifetime issues), or do you want a thread object that blocks when it gets destroyed, without you having to join it first.
In terms of functionality these both implementation are capable to server the purpose, the only difference i can see in these two implementation is, Snippet 2 can accept both lvalue(glvalue) and rvalue(prvalue) but Snippet 1 can't accept rvalue(prvalue) as constructor argument. For example consider following code,
std::thread getThread()
{
return std::thread([](){ std::cout<< __PRETTY_FUNCTION__<< std::endl;});
}
int main( int , char *[])
{
thread_guard g( getThread());
return 0;
}
Now if you compile this code, compile will give following error,
error: cannot bind non-const lvalue reference of type ‘std::thread&’ to an rvalue of type ‘std::remove_reference<std::thread&>::type’ {aka ‘std::thread’}
explicit thread_guard(std::thread _t): t(std::move( _t)){ std::cout<< __PRETTY_FUNCTION__<< std::endl;}
But snippet 2 implementation will work fine.
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.
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?
this is the next step after this topic: Modifying data in threads
class Nginx_sender
{
private:
std::atomic_int data;
boost::mutex mMutex;
void SendMessage(const std::string &msg)
{
mMutex.lock();
data++;
mMutex.unlock();
std::cout << "DATA: " << data << std::endl;
}
void NewThreadFunction()
{
while(true) {
mMutex.lock();
std::cout << data;
mMutex.unlock();
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
}
}
};
int main()
{
Nginx_sender *NginxSenderHandle;
boost::thread sender(boost::bind(&Nginx_sender::NewThreadFunction, &NginxSenderHandle));
// ...
}
In NewThreadFunction the data is always 0 and in SendMessage it changes each time I call SendMessage. So, what's the right way to work with this?
Why are you passing a Nginx_sender ** (double pointer) to boost::bind? That seems wrong, and would explain why your thread appears to be operating on a second copy of the object than the main thread.
Remove the & from the second argument to bind. You already have a pointer to the object, and that's what you're likely trying to use. Secondly, the pointer is uninitialized which could also be a source of you problem. Note, you'll have to be sure the object remains valid until the thread is joined.
int main()
{
Nginx_sender *NginxSenderHandle = new Nginx_sender ;
boost::thread sender(boost::bind(&Nginx_sender::NewThreadFunction, NginxSenderHandle));
// ...
}