I would like to create boost::thread without passing callable object to constructor ( not-any-thread state ).
boost::shared_ptr<boost::thread> ThreadHandle_.reset( new boost::thread() );
but how can i later pass callable object ?
void foo() { }
boost::thread th; // not-any-thread
th = boost::thread(foo); // bound
You can do exactly the same with the shared ptr complication
You can create your own wrapper on top of boost::thread, something similar to:
class QThread
{
public:
QThread();
virtual ~QThread();
void operator()(const boost::function0<void>& action);
void Join();
private:
void Process();
std::list<boost::function0<void> > m_Queue;
bool m_Destroy;
boost::condition_variable_any m_Available;
boost::mutex m_QueueLock;
boost::barrier m_Barrier;
boost::thread m_Thread;
};
and implement Process in a way it wait until you put something to do ( a task, as a callable function in the queue)
void QThread::Process()
{
m_Barrier.wait();
boost::mutex::scoped_lock lock(m_QueueLock);
while(!m_Destroy)
{
while(!m_Destroy && !m_Queue.empty())
{
boost::function0<void> action = m_Queue.front();
m_Queue.pop_front();
lock.unlock();
action();
lock.lock();
}
if (!m_Destroy)
{
m_Available.wait(lock);
}
}
}
Related
I have an very delicate deadlock bug when I use the shared_ptr with custom Deleter and boost::share_mutex:
First there is an WorkManager class to manage Work object:
class Work;
class WorkManager {
public:
static WorkManager& instance() {
static WorkManager instance;
return instance;
}
std::shared_ptr<Work> get(int id);
std::shared_ptr<Work> create(int id);
void update(unsigned int diff);
private:
void _remove(int id, Work* t);
WorkManager();
mutable boost::shared_mutex _mutex;
std::map<int, std::weak_ptr<Work>> _works;
};
void WorkManager::_remove(int id, Work* t)
{
BOOST_ASSERT(t);
std::lock_guard<boost::shared_mutex> lock(_mutex);
_works.erase(id);
delete t;
}
std::shared_ptr<Work> WorkManager::get(int id) {
boost::shared_lock<boost::shared_mutex> lock(_mutex);
auto iter = _works.find(id);
if(iter == _works.end())
return nullptr;
return iter->second.lock();
}
std::shared_ptr<Work> WorkManager::create(int id) {
Work* t = new Work(id);
std::shared_ptr<Work> res;
res.reset(t, std::bind(&WorkManager::_remove, this, t->id(), std::placeholders::_1));
std::lock_guard<boost::shared_mutex> lock(_mutex);
_works[res->id()] = res;
return res;
}
void WorkManager::update(unsigned int diff) {
boost::shared_lock<boost::shared_mutex> lock(_mutex);
for(auto& t : _works)
{
if(std::shared_ptr<Work> work = t.second.lock())
work->update(diff);
}
}
WorkManager::update() is triggered by a timer, called at a fixed interval like 100ms. Because WorkManager doesn't hold shared_ptr<Work> but only weak_ptr<Work>, after work->update(diff); returns the work may be destroyed because there may be no shared_ptr<Work> holding this particular work any more. Then the WorkManager::_remove() will be called via the custom deleter for the shared_ptr<Work>. Notice the update thread already hold a read lock, in _remove(), it needs to acquire a write lock. However it must release the read lock before it can acquire this write lock. So this thread is dead.
This problem means that I cannot write any Manager's function do things like:
boost::shared_lock<boost::shared_mutex> lock(_mutex);
for(auto& t : _works)
{
if(std::shared_ptr<Work> w = t.second.lock())
w->do_something();
}
How to solve this? I figure out a solution is:
std::vector<std::shared_ptr<Work>> tmp;
{
boost::shared_lock<boost::shared_mutex> lock(_mutex);
for(auto& t : _works)
{
if(std::shared_ptr<Work> w = t.second.lock())
{
w->do_something();
tmp.push_back(w); //prevent w destroy before the read lock unlock
}
}
}
However this is error-prone, if someone forget this trick.
I'm new to C++11 threading and I'm trying to do something as follows:
class Something {
public:
void start() {
this->task_ = std::thread(&Something::someTask, this);
this->isRunning_ = true;
this->task_.detach(); // I read detach will stop it from hanging
}
void stop() {
this->isRunning = false;
}
~Something() {
this->stop();
}
private:
std::atomic<bool> isRunning_;
std::thread task_;
void someTask()
{
while(this->isRunning_) {
// do something forever
}
}
};
Something whatever;
whatever.start();
However, the thread keeps getting blocked. Like nothing after whatever.start() executes. It just hangs while the loop runs.
The usual pattern to do this is
class Something {
public:
void start() {
this->task_ = std::thread(&Something::someTask, this);
// this->task_.detach(); <<<<<< Don't do that.
}
void stop() {
this->isRunning_ = false;
task_.join(); // <<< Instead of detaching the thread, join() it.
}
~Something() {
this->stop();
}
private:
std::atomic<bool> isRunning_;
std::thread task_;
void someTask()
{
this->isRunning_ = true;
while(this->isRunning_) {
// do something forever
}
}
};
Detaching a std::thread usually isn't a good idea, unless there's some kind of synchronization set up, that allows to wait for the thread execution to end before the process ends as a whole.
Demonizing a process usually is realized with a fork() to create a background child process, and leave the parent process to return control to the caller.
I recently wrote a generic class that does just this
#include<functional>
#include<thread>
//do action asynchronously until condition is false
class do_async_until{
public:
do_async_until(std::function<void(void)> action,
std::function<bool(void)> condition);
~do_async_until();
void start();
void stop();
private:
void _do();
std::thread _worker;
std::function<void(void)> _action;
std::function<bool(void)> _condition;
};
//implementation
do_async_until::do_async_until(std::function<void(void)> action,
std::function<bool(void)> condition):_action(action),
_condition(condition){
}
do_async_until::~do_async_until(){
stop();
}
void do_async_until::start(){
_worker = std::thread(std::bind(&do_async_until::_do,this));
}
void do_async_until::stop(){
if(_worker.joinable()){
_worker.join();
}
}
void do_async_until::_do(){
while (_condition())
{
_action();
}
}
this will run any function with the signiture void(void) until the condition function bool(void) returns true
example usage:
int main(int agrc,char** argv){
bool running = true;
auto do_this = [](){
std::cout<<"hello world"<<std::endl;
};
auto condition = [&](){
return running;
};
do_async_until async(do_this,condition);
async.start();
std::this_thread::sleep_for(std::chrono::seconds(1));
running=false;
return 0;
}
The example should print "hello world" a bunch of times for one seconds then exit.
EDIT: to make this work with a member function you simply need to have an instance of do_async_until inside you class and pass the member function to the constructor of do_async_until using std::bind(&foo::func,this)
Okay this meight be a bit off for Stack but ill try to keep it as short as possible.
I got thread which takes tasks out of a list and executes them. Simple as this (The worker class has its own thread and runs doTask m_thread(&Worker::doTask, this)):
void Worker::doTask()
{
while (m_running)
{
auto task = m_tasks.pop_front();
task->execute();
if (task->isContinuous())
m_tasks.push_pack(task);
}
}
The list itself is/should be threadsafe:
Header:
class TaskQueue
{
public:
void push_pack(std::shared_ptr<Task> t);
std::shared_ptr<Task> pop_front();
private:
std::list<std::shared_ptr<Task>> m_tasks;
std::condition_variable m_cond;
std::mutex m_mutex;
void TaskQueue::push_pack(std::shared_ptr<Task> t)
}
Impls of the importand part:
void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}
std::shared_ptr<Task> TaskQueue::pop_front()
{
//regular lock so noone else acces this area now
std::unique_lock<std::mutex> lock(m_mutex);
while (m_tasks.size() == 0)
m_cond.wait(lock);
auto task = m_tasks.front();
m_tasks.pop_front();
return task;
}
last but not least the tasks:
class Task
{
public:
virtual ~Task()
{
}
virtual void execute() = 0;
virtual bool isContinuous()
{
return false;
};
};
So if i try to add this Task:
class NetworkRequestTask:public Task
{
public:
NetworkRequestTask(TaskQueue &q);
~NetworkRequestTask();
void execute() override;
bool isContinuous() override;
private:
TaskQueue &m_tasks;
};
Impl:
NetworkRequestTask::NetworkRequestTask(TaskQueue& q): m_tasks(q)
{
}
NetworkRequestTask::~NetworkRequestTask()
{
}
void NetworkRequestTask::execute()
{
while(dosomething)
{
//do something here
}
}
bool NetworkRequestTask::isContinuous()
{
return true;
}
Main:
int main(int argc, char* argv[])
{
TaskQueue tasks;
tasks.push_pack(std::make_shared<NetworkRequestTask>(tasks));
}
it gets into a bad state:
Expression: list iterator not derefercable
I am Confused. This only happens if i override continouse and this only happens at this task. If i add the queue to a other continouse task as reference it does not get into that bad state.
So whats going wrong here and more importand what have i done wrong?
As from the comments, i already tried to lock the push_back method which did not change anything to the behaviour. (You can exchange it for a regular mutex it doesnt matter.)
void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
std::lock_guard<SpinLock> lock(m_spin);
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}
I have an object that runs around a boost::asio::io_service which has some properties. Something like that:
class Foo
{
private:
// Not an int in my real code, but it doesn't really matter.
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};
m_bar is to be used only from a handler that is called through the strand m_bar_strand. This allows me not to lock from within those handlers.
To set the m_bar property from outside a thread that runs io_service::run() I wrote an asynchronous_setter, like so:
class Foo
{
public:
void async_get_bar(function<void (int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, handler));
}
void async_set_bar(int value, function<void ()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}
private:
void do_get_bar(function<void (int)> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
// Run the handler to notify the caller.
handler(m_bar);
}
void do_set_bar(int value, function<void ()> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
m_bar = value;
// Run the handler to notify the caller.
handler();
}
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};
This works perfectly but now I'd like to write a synchronous version of set_bar that sets the value and returns only when the set was effective. It must still guarantee that the effective set will occur within the m_bar_strand. Ideally, something reentrant.
I can imagine solutions with semaphores that would be modified from within the handler but everything I come up seems hackish and really not elegant. Is there something in Boost/Boost Asio that allows such a thing?
How would you proceed to implement this method?
If you need to synchronously wait on a value to be set, then Boost.Thread's futures may provide an elegant solution:
The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or on a single thread in response to external stimuli, or on-demand.
In short, a boost::promise is created and allows for a value to be set on it. The value can later be retrieved via an associated boost::future. Here is a basic example:
boost::promise<int> promise;
boost::unique_future<int> future = promise.get_future();
// start asynchronous operation that will invoke future.set_value(42)
...
assert(future.get() == 42); // blocks until future has been set.
Two other notable benefits to this approach:
future is part of C++11.
Exceptions can even be passed to future via promise::set_exception(), supporting an elegant way to provide exceptions or errors to the caller.
Here is a complete example based on the original code:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
class Foo
{
public:
Foo(boost::asio::io_service& io_service)
: m_io_service(io_service),
m_bar_strand(io_service)
{}
public:
void async_get_bar(boost::function<void(int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, handler));
}
void async_set_bar(int value, boost::function<void()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}
int bar()
{
typedef boost::promise<int> promise_type;
promise_type promise;
// Pass the handler to async operation that will set the promise.
void (promise_type::*setter)(const int&) = &promise_type::set_value;
async_get_bar(boost::bind(setter, &promise, _1));
// Synchronously wait for promise to be fulfilled.
return promise.get_future().get();
}
void bar(int value)
{
typedef boost::promise<void> promise_type;
promise_type promise;
// Pass the handler to async operation that will set the promise.
async_set_bar(value, boost::bind(&promise_type::set_value, &promise));
// Synchronously wait for the future to finish.
promise.get_future().wait();
}
private:
void do_get_bar(boost::function<void(int)> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
// Run the handler to notify the caller.
handler(m_bar);
}
void do_set_bar(int value, boost::function<void()> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
m_bar = value;
// Run the handler to notify the caller.
handler();
}
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};
int main()
{
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
boost::thread t(
boost::bind(&boost::asio::io_service::run, boost::ref(io_service)));
Foo foo(io_service);
foo.bar(21);
std::cout << "foo.bar is " << foo.bar() << std::endl;
foo.bar(2 * foo.bar());
std::cout << "foo.bar is " << foo.bar() << std::endl;
io_service.stop();
t.join();
}
which provides the following output:
foo.bar is 21
foo.bar is 42
You could use a pipe to notify the synchronous method when the value is set in async_set_bar(). Warning, the below code is brain-compiled and likely has errors but it should get the point across
#include <boost/asio.hpp>
#include <iostream>
#include <thread>
class Foo
{
public:
Foo( boost::asio::io_service& io_service ) :
_bar( 0 ),
_io_service( io_service ),
_strand( _io_service ),
_readPipe( _io_service ),
_writePipe( _io_service )
{
boost::asio::local::connect_pair( _readPipe, _writePipe );
}
void set_async( int v ) {
_strand.post( [=]
{
_bar = v;
std::cout << "sending " << _bar << std::endl;
_writePipe.send( boost::asio::buffer( &_bar, sizeof(_bar) ) );
}
);
}
void set_sync( int v ) {
this->set_async( v );
int value;
_readPipe.receive( boost::asio::buffer(&value, sizeof(value) ) );
std::cout << "set value to " << value << std::endl;
}
private:
int _bar;
boost::asio::io_service& _io_service;
boost::asio::io_service::strand _strand;
boost::asio::local::stream_protocol::socket _readPipe;
boost::asio::local::stream_protocol::socket _writePipe;
};
int
main()
{
boost::asio::io_service io_service;
boost::asio::io_service::work w(io_service);
std::thread t( [&]{ io_service.run(); } );
Foo f( io_service );
f.set_sync( 20 );
io_service.stop();
t.join();
}
if you are unable to use c++11 lambdas, replace them with boost::bind and some more completion handler methods.
This is what I came up with:
class synchronizer_base
{
protected:
synchronizer_base() :
m_has_result(false),
m_lock(m_mutex)
{
}
void wait()
{
while (!m_has_result)
{
m_condition.wait(m_lock);
}
}
void notify_result()
{
m_has_result = true;
m_condition.notify_all();
}
private:
boost::atomic<bool> m_has_result;
boost::mutex m_mutex;
boost::unique_lock<boost::mutex> m_lock;
boost::condition_variable m_condition;
};
template <typename ResultType = void>
class synchronizer : public synchronizer_base
{
public:
void operator()(const ResultType& result)
{
m_result = result;
notify_result();
}
ResultType wait_result()
{
wait();
return m_result;
}
private:
ResultType m_result;
};
template <>
class synchronizer<void> : public synchronizer_base
{
public:
void operator()()
{
notify_result();
}
void wait_result()
{
wait();
}
};
And I can use it, that way:
class Foo
{
public:
void async_get_bar(function<void (int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, value, handler));
}
void async_set_bar(int value, function<void ()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}
int get_bar()
{
synchronizer<int> sync;
async_get_bar(boost::ref(sync));
return sync.wait_result();
}
void set_bar(int value)
{
synchronizer<void> sync;
async_set_bar(value, boost::ref(sync));
sync.wait_result();
}
};
The boost::ref is necessary because the instances of synchronizer are non-copyable. This could be avoided by wrapping synchronizer in some other container-class, but I'm fine with that solution as it is.
Note: Do NOT call such "synchronized" functions from inside a handler or it might just deadlock !
I am running function Foo from somebody else's library in a single-threaded application currently. Most of the time, I make a call to Foo and it's really quick, some times, I make a call to Foo and it takes forever. I am not a patient man, if Foo is going to take forever, I want to stop execution of Foo and not call it with those arguments.
What is the best way to call Foo in a controlled manner (my current environment is POSIX/C++) such that I can stop execution after a certain number of seconds. I feel like the right thing to do here is to create a second thread to call Foo, while in my main thread I create a timer function that will eventually signal the second thread if it runs out of time.
Is there another, more apt model (and solution)? If not, would Boost's Signals2 library and Threads do the trick?
You can call Foo on a second thread with a timeout. For example:
#include <boost/date_time.hpp>
#include <boost/thread/thread.hpp>
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(500);
boost::thread thrd(&Foo);
if (thrd.timed_join(timeout))
{
//finished
}
else
{
//Not finished;
}
You can use the following class:
class timer
{
typedef boost::signals2::signal<void ()> timeout_slot;
public:
typedef timeout_slot::slot_type timeout_slot_t;
public:
timer() : _interval(0), _is_active(false) {};
timer(int interval) : _interval(interval), _is_active(false) {};
virtual ~timer() { stop(); };
inline boost::signals2::connection connect(const timeout_slot_t& subscriber) { return _signalTimeout.connect(subscriber); };
void start()
{
boost::lock_guard<boost::mutex> lock(_guard);
if (is_active())
return; // Already executed.
if (_interval <= 0)
return;
_timer_thread.interrupt();
_timer_thread.join();
timer_worker job;
_timer_thread = boost::thread(job, this);
_is_active = true;
};
void stop()
{
boost::lock_guard<boost::mutex> lock(_guard);
if (!is_active())
return; // Already executed.
_timer_thread.interrupt();
_timer_thread.join();
_is_active = false;
};
inline bool is_active() const { return _is_active; };
inline int get_interval() const { return _interval; };
void set_interval(const int msec)
{
if (msec <= 0 || _interval == msec)
return;
boost::lock_guard<boost::mutex> lock(_guard);
// Keep timer activity status.
bool was_active = is_active();
if (was_active)
stop();
// Initialize timer with new interval.
_interval = msec;
if (was_active)
start();
};
protected:
friend struct timer_worker;
// The timer worker thread.
struct timer_worker
{
void operator()(timer* t)
{
boost::posix_time::milliseconds duration(t->get_interval());
try
{
while (1)
{
boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
{
boost::this_thread::disable_interruption di;
{
t->_signalTimeout();
}
}
}
}
catch (boost::thread_interrupted const& )
{
// Handle the thread interruption exception.
// This exception raises on boots::this_thread::interrupt.
}
};
};
protected:
int _interval;
bool _is_active;
boost::mutex _guard;
boost::thread _timer_thread;
// Signal slots
timeout_slot _signalTimeout;
};
An example of usage:
void _test_timer_handler()
{
std::cout << "_test_timer_handler\n";
}
BOOST_AUTO_TEST_CASE( test_timer )
{
emtorrus::timer timer;
BOOST_CHECK(!timer.is_active());
BOOST_CHECK(timer.get_interval() == 0);
timer.set_interval(1000);
timer.connect(_test_timer_handler);
timer.start();
BOOST_CHECK(timer.is_active());
std::cout << "timer test started\n";
boost::this_thread::sleep<boost::posix_time::milliseconds>(boost::posix_time::milliseconds(5500));
timer.stop();
BOOST_CHECK(!timer.is_active());
BOOST_CHECK(_test_timer_count == 5);
}
You can also set an alarm right before calling that function, and catch SIGALRM.
Vlad, excellent post! Your code compiled and works beautifully. I implemented a software watchdog timer with it. I made a few modifications:
To prevent pointer decay, store the signal in boost::shared_ptr and pass this to the thread worker instead of a weak pointer to the timer class. This eliminates the need for the thread worker to be a friend struct and guarantees the signal is in memory.
Add parameter _is_periodic to allow the caller to select whether or not the worker thread is periodic or if it terminates after expiration.
Store _is_active, _interval and _is_periodic in boost::atomic to allow thread-safe access.
Narrow the scope of mutex locking.
Add reset() method to "kick" the timer, preventing it from issuing the expiration signal.
With these changes applied:
#include <atomic>
#include <boost/signals2.hpp>
#include <boost/thread.hpp>
class IntervalThread
{
using interval_signal = boost::signals2::signal<void(void)>;
public:
using interval_slot_t = interval_signal::slot_type;
IntervalThread(const int interval_ms = 60)
: _interval_ms(interval_ms),
_is_active(false),
_is_periodic(false),
_signal_expired(new interval_signal()) {};
inline ~IntervalThread(void) { stop(); };
boost::signals2::connection connect(const interval_slot_t &subscriber)
{
// thread-safe: signals2 obtains a mutex on connect()
return _signal_expired->connect(subscriber);
};
void start(void)
{
if (is_active())
return; // Already executed.
if (get_interval_ms() <= 0)
return;
boost::lock_guard<boost::mutex> lock(_timer_thread_guard);
_timer_thread.interrupt();
_timer_thread.join();
_timer_thread = boost::thread(timer_worker(),
static_cast<int>(get_interval_ms()),
static_cast<bool>(is_periodic()),
_signal_expired);
_is_active = true;
};
void reset(void)
{
if (is_active())
stop();
start();
}
void stop(void)
{
if (!is_active())
return; // Already executed.
boost::lock_guard<boost::mutex> lock(_timer_thread_guard);
_timer_thread.interrupt();
_timer_thread.join();
_is_active = false;
};
inline bool is_active(void) const { return _is_active; };
inline int get_interval_ms(void) const { return _interval_ms; };
void set_interval_ms(const int interval_ms)
{
if (interval_ms <= 0 || get_interval_ms() == interval_ms)
return;
// Cache timer activity state.
const bool was_active = is_active();
// Initialize timer with new interval.
if (was_active)
stop();
_interval_ms = interval_ms;
if (was_active)
start();
};
inline bool is_periodic(void) const { return _is_periodic; }
inline void set_periodic(const bool is_periodic = true) { _is_periodic = is_periodic; }
private:
// The timer worker for the interval thread.
struct timer_worker {
void operator()(const int interval_ms, const bool is_periodic, boost::shared_ptr<interval_signal> signal_expired)
{
boost::posix_time::milliseconds duration(interval_ms);
try {
do {
boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
{
boost::this_thread::disable_interruption di;
signal_expired->operator()();
}
} while (is_periodic);
} catch (const boost::thread_interrupted &) {
// IntervalThread start(), stop() and reset() throws boost::this_thread::interrupt,
// which is expected since this thread is interrupted. No action neccessary.
}
};
};
std::atomic<int> _interval_ms; // Interval, in ms
std::atomic<bool> _is_active; // Is the timed interval active?
std::atomic<bool> _is_periodic; // Is the timer periodic?
boost::mutex _timer_thread_guard;
boost::thread _timer_thread;
// The signal to call on interval expiration.
boost::shared_ptr<interval_signal> _signal_expired;
};