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";
}
Related
I need something to suspend Lambdas in C++ and resume them. I try to narrow it down to a very simple example:
Lets assume I have a singleton class orchestrator where I can register a lambda:
int main() {
orchestrator::getInstance().registerLambda([&](){
// Do something:
...
wait(); // Suspend here
// When waked up continue here:
...
wait(); // Suspend here
...
});
orchestrator::start()
}
In the orchestrator class itself there is a main loop which calls then this lambda-function from time to time.
orchestrator::start()
{
while(true) {
lambda();
// Do other stuff:
...
}
}
I thought about co-routines but they seam to complex in my opinion. The solution should stick with the concept of lambda and standard C++. Modern C++ like '11, '17 or '20 would also be fine.
In the interest of the future where coroutine support will be more complete, here's one way a coroutine could look:
resumable foo() {
std::cout << "Starting foo\n";
while (true) {
co_await std::suspend_always{}; // Could be co_await wait(); if you prefer, if wait() returns suspend_always
std::cout << "Resuming foo\n";
}
}
int main() {
auto m = foo();
for (int i = 0; i < 5; ++i) {
std::cout << "Back in main to resume foo\n";
m();
}
std::cout << "Done main\n";
}
This outputs "Starting foo", followed by 5 back-and-forths between main and foo, and then "Done main". Using a lambda is trivial: specify resumable as the return type. (See the live example)
The messy part is defining resumable, and this part belongs in a library. I'd say it's a good candidate for the standard library in some form after some more common types like task and generator. In fact, this type is basically a generator<void> with a different iteration API. Without using a library, it's not too bad, but note that I haven't bothered to do things like define what happens if you try to resume the lambda after it's done:
class resumable {
std::coroutine_handle<> _coro;
explicit resumable(std::coroutine_handle<> h) noexcept
: _coro(h) {}
public:
// All fluff except for giving resumable a coroutine handle
struct promise_type {
resumable get_return_object() noexcept { return resumable(std::coroutine_handle<promise_type>::from_promise(*this)); }
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() noexcept {}
void unhandled_exception() noexcept {}
};
// This is how the caller interacts, they just call this object repeatedly.
void operator()() const noexcept {
_coro.resume();
}
};
If not using coroutines, it's back to good old state machines:
struct state_resumable {
// TODO: Store all state
state_resumable() {
std::cout << "Starting resumable\n";
}
void operator()() {
// TODO: Figure out what to execute next based on the stored state
std::cout << "Resuming resumable\n";
}
};
int main() {
auto m = state_resumable();
for (int i = 0; i < 5; ++i) {
std::cout << "Back in main to resume resumable\n";
m();
}
std::cout << "Done main\n";
}
What isn't shown here is the effort required to manually keep track of state. Coroutines automatically store away the local variables in your function and restore them when the coroutine is resumed, plus keep track of which part of the function to execute next. With a state machine, you have to do all of these yourself. You cannot use a single lambda as above because only coroutines can actually suspend mid-execution. With a state machine, you're pretending to do this, but the function must actually finish completely each time.
I want to create a container that I can push functions into, that will instantly be started in a thread. Once the function is complete, it should automatically be removed from the container so that the container does not grow indefinitely.
Here is my attempt so far:
#include <thread>
#include <future>
#include <iostream>
#include <map>
class j_thread {
std::thread thread;
public:
j_thread() {}
template<typename F>
j_thread(const F& f) : thread(f) {}
j_thread& operator = (j_thread&& other) {
this->thread.swap(other.thread);
return *this;
}
virtual ~j_thread() {
thread.join();
}
};
class jobs {
std::map<size_t, j_thread> threads;
public:
template<typename F>
void add_job(const F &function) {
size_t job_id = threads.size();
auto wrapped_function = [&function, job_id, this]() {
function();
threads.erase(job_id);
};
threads[job_id] = j_thread(wrapped_function);
}
void wait_for_all() {
while(threads.size() != 0) {}
}
};
int main() {
jobs j;
j.add_job([](){std::cout << "hello" << std::endl;});
j.add_job([](){std::cout << "world" << std::endl;});
j.wait_for_all();
}
But when run gives the error:
terminate called after throwing an instance of 'std::system_error'
what(): Invalid argument
hello
terminate called recursively
12:15:44: The program has unexpectedly finished.
Calling join within the body of thread is undefined behaviour.
Look at error conditions for join:
Error Conditions resource_deadlock_would_occur if this->get_id() ==
std::this_thread::get_id() (deadlock detected)
Your body is:
auto wrapped_function = [&function, job_id, this]() {
function();
threads.erase(job_id);
};
where you call erase, dtor of jthread is being called which calls join on joinable thread.
Instead of join, in dtor you should call detach.
To avoid dangling reference function must be captured by value.
Also you have to add some mutex to avoid data race on map, when calling size and erase:
std::mutex m;
int size() {
std::lock_guard<std::mutex> lock{m};
return threads.size();
}
auto wrapped_function = [f = function, job_id, this]() {
f();
std::lock_guard<std::mutex> l(m);
threads.erase(job_id);
};
void wait_for_all() {
while(size() != 0) {}
}
Demo
Why should I use enable_shared_from_this as I can get the same effect via plain assignment also.
struct A : std::enable_shared_from_this<A> {
std::shared_ptr<A> getptr() {
return shared_from_this();
}
};
int main () {
// What is the differentce between this code
std::shared_ptr<A> p1 = make_shared<A>();
std::shared_ptr<A> p2 = p1->getptr();
// Vs this
std::shared_ptr<A> p1 = make_shared<A>();
std::shared_ptr<A> p2 = p1;
}
Because you can't get the "same" effect", at least not the one you may be thinking of.
There is no difference in the posted code methodologies, precisely because A inherits from std::enable_shared_from_this<A>. Both p1 and p2 are shared_ptr objects referring to the same concrete object (assuming only one of those sections is compiled for your tests, else you error on id name reuse).
std::enable_shared_from_this<T> allows you to acquire a std::shared_ptr<T> from some object, formally managed by some preexisting std::shared_ptr<T> of type T or derivative thereof, in locations where you have no std::shared_ptr<T> to the object to otherwise acquire, but need one for one reason or another. For example:
#include <iostream>
#include <memory>
struct A;
void foo(std::shared_ptr<A> arg)
{
}
struct A : std::enable_shared_from_this<A>
{
void method()
{
foo(shared_from_this());
}
};
int main ()
{
auto a = std::make_shared<A>();
a->method();
}
In the above example, foo requires a std::shared_ptr<A> as a parameter. From the body of A::method() no such mechanism exists without std::enable_shared_from_this<A> as a base. Without the std::enabled_shared_from_this<T> base, you would have to provide an alternative mechanism for passing the a shared pointer down the call chain until it reached foo. In short it would look something like this:
#include <iostream>
#include <memory>
struct A;
void foo(std::shared_ptr<A> arg)
{
}
struct A
{
void method(std::shared_ptr<A> me)
{
foo(me);
}
};
int main ()
{
std::shared_ptr<A> a = std::make_shared<A>();
a->method(a);
}
which is obviously dreadful and hideous. Further, there is no guarantee me in method is actually a std::shared_ptr<T> of this. Thus the standards committee blessed us with std::enable_shared_from_this<T>.
It's probably worth mentioning what shared_from_this is 'for'.
The most common use case is to 'keep myself alive' while some asynchronous process is running. A good example of this would be a completion handler, another would be a callback on 'this' when this is controlled by a shared_ptr.
for example:
#include <memory>
#include <future>
#include <thread>
#include <chrono>
#include <iostream>
using namespace std::literals;
template<class Handler>
void long_process_with_completion_handler(Handler done)
{
std::thread([done] {
std::cout << "long process starts" << std::endl;
std::this_thread::sleep_for(2000ms);
done();
}).detach();
}
struct controller : std::enable_shared_from_this<controller>
{
auto get_lock() const {
return std::unique_lock<std::mutex>(_mutex);
}
void start() {
long_process_with_completion_handler([self = shared_from_this()] {
auto lock = self->get_lock();
std::cout << "all complete" << std::endl;
});
}
mutable std::mutex _mutex;
};
int main()
{
std::condition_variable controller_done;
std::mutex done_mutex;
bool is_controller_done = 0;
// make shared controller
// start its processing
auto pcontroller = std::shared_ptr<controller>{ new controller,
[&](auto*p) {
delete p;
auto lock = std::unique_lock<std::mutex>(done_mutex);
is_controller_done = true;
std::cout << "controller destroyed" << std::endl;
lock.unlock();
controller_done.notify_all();
}};
pcontroller->start();
// destroy the controlling pointer. but our controller is still running...
pcontroller.reset();
auto lock = std::unique_lock<std::mutex>(done_mutex);
controller_done.wait(lock, [&]{ return is_controller_done;});
std::cout << "program ends" << std::endl;
}
The shared-from-this functionality enables you to obtain a shared_ptr to a shared_ptr-managed object when all you have is a raw pointer or a reference.
Just creating a shared_ptr directly from the raw pointer would create a new, unrelated reference counter.
The use case of enable_shared_from_this and shared_from_this is clear, and yet I tend to say that in most use cases it can be dropped in favor of a static method that gets a shared_ptr and then creates a new shared_ptr from it (in a very similar manner to the approach suggested by the OP, but with a static method to support the creation of the new shared_ptr).
The advantage of the static method approach is that you won't fall in the bug of trying to get shared_from_this when there is no underlying shared_ptr for this instance, resulting with bad_weak_ptr.
The disadvantage is that the API is implicitly asking the caller to come with a shared_ptr, so if the caller has just a raw pointer to an instance he can't use it (the caller may create a shared_ptr from the raw pointer and call the method, but how can he tell if the original raw pointer was not managed already by a shared_ptr?). On the other hand, if the user has in hand a unique_ptr he should be positively sure that turning it to shared_ptr in order to call the static method should be fine.
In a way the advantage and disadvantage are two sides of the same coin.
I would prefer in most cases to require the API to work with shared_ptr (it already depends on that in a way) rather than allowing working with any kind of a pointer, with the hope that there is a managed shared_ptr for it. This goes well with the advice of having APIs that cannot be easily used in a wrong way.
Here is the code presented by #RichardHodges (great example!) using the static method approach instead of using enable_shared_from_this:
// code based on Richard Hodges example
template<class Handler>
void long_process_with_completion_handler(Handler done) {
std::thread([done] {
std::cout << "long process starts" << std::endl;
std::this_thread::sleep_for(2000ms);
done();
}).detach();
}
// without the need to inherit from std::enable_shared_from_this
struct Controller {
auto get_lock() const {
return std::unique_lock<std::mutex>(_mutex);
}
static void start(std::shared_ptr<Controller>& pcontroller) {
long_process_with_completion_handler(
[self = std::shared_ptr<Controller>(pcontroller)] {
auto lock = self->get_lock();
std::cout << "all complete" << std::endl;
});
}
mutable std::mutex _mutex;
};
int main() {
std::condition_variable controller_done;
std::mutex done_mutex;
bool is_controller_done = 0;
// make shared controller and start its processing
auto pcontroller = std::shared_ptr<Controller>{ new Controller,
[&](auto*p) {
delete p;
auto lock = std::unique_lock<std::mutex>(done_mutex);
is_controller_done = true;
std::cout << "controller destroyed" << std::endl;
lock.unlock();
controller_done.notify_all();
}};
Controller::start(pcontroller);
// destroy the controlling pointer. but our controller is still running...
pcontroller.reset();
auto lock = std::unique_lock<std::mutex>(done_mutex);
controller_done.wait(lock, [&]{ return is_controller_done;});
std::cout << "program ends" << std::endl;
}
Code: http://coliru.stacked-crooked.com/a/281b0ef6d1b31c56
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.
I have a custom class that uses boost mutexes and locks like this (only relevant parts):
template<class T> class FFTBuf
{
public:
FFTBuf();
[...]
void lock();
void unlock();
private:
T *_dst;
int _siglen;
int _processed_sums;
int _expected_sums;
int _assigned_sources;
bool _written;
boost::recursive_mutex _mut;
boost::unique_lock<boost::recursive_mutex> _lock;
};
template<class T> FFTBuf<T>::FFTBuf() : _dst(NULL), _siglen(0),
_expected_sums(1), _processed_sums(0), _assigned_sources(0),
_written(false), _lock(_mut, boost::defer_lock_t())
{
}
template<class T> void FFTBuf<T>::lock()
{
std::cerr << "Locking" << std::endl;
_lock.lock();
std::cerr << "Locked" << std::endl;
}
template<class T> void FFTBuf<T>::unlock()
{
std::cerr << "Unlocking" << std::endl;
_lock.unlock();
}
If I try to lock more than once the object from the same thread, I get an exception (lock_error):
#include "fft_buf.hpp"
int main( void ) {
FFTBuf<int> b( 256 );
b.lock();
b.lock();
b.unlock();
b.unlock();
return 0;
}
This is the output:
sb#dex $ ./src/test
Locking
Locked
Locking
terminate called after throwing an instance of 'boost::lock_error'
what(): boost::lock_error
zsh: abort ./src/test
Why is this happening? Am I understanding some concept incorrectly?
As the name implies, the Mutex is recursive but the Lock is not.
That said, you have here a design problem. The locking operations would be better off not being accessible from the outside.
class SynchronizedInt
{
public:
explicit SynchronizedInt(int i = 0): mData(i) {}
int get() const
{
lock_type lock(mMutex);
toolbox::ignore_unused_variable_warning(lock);
return mData;
}
void set(int i)
{
lock_type lock(mMutex);
toolbox::ignore_unused_variable_warning(lock);
mData = i;
}
private:
typedef boost::recursive_mutex mutex_type;
typedef boost::unique_lock<mutex_type> lock_type;
int mData;
mutable mutex_type mMutex;
};
The main point of the recursive_mutex is to allow chain locking in a given thread which may occur if you have complex operations that call each others in some case.
For example, let's add tweak get:
int SynchronizedInt::UnitializedValue = -1;
int SynchronizedInt::get() const
{
lock_type lock(mMutex);
if (mData == UnitializedValue) this->fetchFromCache();
return mData;
}
void SynchronizedInt::fetchFromCache()
{
this->set(this->fetchFromCacheImpl());
}
Where is the problem here ?
get acquires the lock on mMutex
it calls fetchFromCache which calls set
set attempts to acquire the lock...
If we did not have a recursive_mutex, this would fail.
The lock should not be part of the protected ressource but of the caller as you have one caller by thread. They must use different unique_lock.
The purpose of unique_lock is to lock and release the mutex with RAII, so you don't have to call unlock explicitly.
When the unique_lock is declared inside a method body, it will belong to the calling thread stack.
So a more correct use is :
#include <boost/thread/recursive_mutex.hpp>
#include <iostream>
template<class T>
class FFTBuf
{
public :
FFTBuf()
{
}
// this can be called by any thread
void exemple() const
{
boost::recursive_mutex::scoped_lock lock( mut );
std::cerr << "Locked" << std::endl;
// we are safe here
std::cout << "exemple" << std::endl ;
std::cerr << "Unlocking ( by RAII)" << std::endl;
}
// this is mutable to allow lock of const FFTBuf
mutable boost::recursive_mutex mut;
};
int main( void )
{
FFTBuf< int > b ;
{
boost::recursive_mutex::scoped_lock lock1( b.mut );
std::cerr << "Locking 1" << std::endl;
// here the mutex is locked 1 times
{
boost::recursive_mutex::scoped_lock lock2( b.mut );
std::cerr << "Locking 2" << std::endl;
// here the mutex is locked 2 times
std::cerr << "Auto UnLocking 2 ( by RAII) " << std::endl;
}
b.exemple();
// here the mutex is locked 1 times
std::cerr << "Auto UnLocking 1 ( by RAII) " << std::endl;
}
return 0;
}
Note the mutable on the mutex for const methods.
And the boost mutex types have a scoped_lock typedef which is the good unique_lock type.
Try this:
template<class T> void FFTBuf<T>::lock()
{
std::cerr << "Locking" << std::endl;
_mut.lock();
std::cerr << "Locked" << std::endl;
}
template<class T> void FFTBuf<T>::unlock()
{
std::cerr << "Unlocking" << std::endl;
_mut.unlock();
}
You use the same instance of unique_lock _lock twice and this is a problem.
You either have to directly use methods lock () and unock() of the recursive mutex or use two different instances of unique_lock like foe example _lock and _lock_2;.
Update
I would like to add that your class has public methods lock() and unlock() and from my point of view in a real program it is a bad idea. Also having unique_lock as a member of class in a real program must be often a bad idea.