destroy thread's object from a joinable thread - c++

struct Foo
{
boost::thread thread_;
void launchThread()
{
boost::thread(boost::bind(&Foo::worker, this));
}
void worker()
{
~Foo();
}
~Foo()
{
if (boost::this_thread::get_id() != thread_.get_id())
thread_.join();
}
};
In c++11 is it legal in a joinable thread to call the destructor of the class which declare the thread?
EDIT1, more realistic example:
struct Holder
{
std::unique_ptr<SocketClient> client_;
void ondisconnected(){client_.release();}
Holder()
{
//create SocketClient and launch the thread
}
}
struct SocketClient
{
boost::thread thread_;
void launchThread()
{
boost::thread(boost::bind(&SocketClient ::worker, this));
}
void worker()
{
run_ = true;
while (run_)
{
boost::system::error_code error;
auto receveidBytesCount = socket_.read_some(boost::asio::buffer(socketBuffer_), error);
if (error == boost::asio::error::eof)
{
disconnected_() // call Holder slot
return;
}
}
}
~SocketClient ()
{
run_ = false;
socket_.shutdown(boost::asio::socket_base::shutdown_both);
socket_.close();
if (boost::this_thread::get_id() == thread_.get_id())
thread_.detach();
else
thread_.join();
}
};

No. A joinable thread must be joined or detached before the thread object is destroyed. This will do neither if called from that thread. The thread's destructor will call terminate(), ending the program.
Whether it's acceptable to detach the thread depends on whether you're also destroying objects which the thread accesses. That rather depends on the large-scale design of your thread interactions, and can't really be answered in general.
Note that explicitly calling the destructor like that is almost certainly not valid; I assume that's just to illustrate that the destructor is being called (in a more suitable manner) on the thread.

Related

Thread-safe reference-counted queue C++

I'm struggling to implement a thread-safe reference-counted queue. The idea is that I have a number of tasks that each maintain a shared_ptr to a task manager that owns the queue. Here is a minimal implementation that should encounter that same issue:
#include <condition_variable>
#include <deque>
#include <functional>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
namespace {
class TaskManager;
struct Task {
std::function<void()> f;
std::shared_ptr<TaskManager> manager;
};
class Queue {
public:
Queue()
: _queue()
, _mutex()
, _cv()
, _running(true)
, _thread([this]() { sweepQueue(); })
{
}
~Queue() { close(); }
void close() noexcept
{
try {
{
std::lock_guard<std::mutex> lock(_mutex);
if (!_running) {
return;
}
_running = false;
}
_cv.notify_one();
_thread.join();
} catch (...) {
std::cerr << "An error occurred while closing the queue\n";
}
}
void push(Task&& task)
{
std::unique_lock<std::mutex> lock(_mutex);
_queue.emplace_back(std::move(task));
lock.unlock();
_cv.notify_one();
}
private:
void sweepQueue() noexcept
{
while (true) {
try {
std::unique_lock<std::mutex> lock(_mutex);
_cv.wait(lock, [this] { return !_running || !_queue.empty(); });
if (!_running && _queue.empty()) {
return;
}
if (!_queue.empty()) {
const auto task = _queue.front();
_queue.pop_front();
task.f();
}
} catch (...) {
std::cerr << "An error occurred while sweeping the queue\n";
}
}
}
std::deque<Task> _queue;
std::mutex _mutex;
std::condition_variable _cv;
bool _running;
std::thread _thread;
};
class TaskManager : public std::enable_shared_from_this<TaskManager> {
public:
void addTask(std::function<void()> f)
{
_queue.push({ f, shared_from_this() });
}
private:
Queue _queue;
};
} // anonymous namespace
int main(void)
{
const auto manager = std::make_shared<TaskManager>();
manager->addTask([]() { std::cout << "Hello world\n"; });
}
The problem I find is that on rare occasions, the queue will try to invoke its own destructor within the sweepQueue method. Upon further inspection, it seems that the reference count on the TaskManager hits zero once the last task is dequeued. How can I safely maintain the reference count without invoking the destructor?
Update: The example does not clarify the need for the std::shared_ptr<TaskManager> within Task. Here is an example use case that should illustrate the need for this seemingly unnecessary ownership cycle.
std::unique_ptr<Task> task;
{
const auto manager = std::make_shared<TaskManager>();
task = std::make_unique<Task>(someFunc, manager);
}
// Guarantees manager is not destroyed while task is still in scope.
The ownership hierarchy here is TaskManager owns Queue and Queue owns Tasks. Tasks maintaining a shared pointer to TaskManager create an ownership cycle which does not seem to serve a useful purpose here.
This is the ownership what is root of the problem here. A Queue is owned by TaskManager, so that Queue can have a plain pointer to TaskManager and pass that pointer to Task in sweepQueue. You do not need std::shared_pointer<TaskManager> in Task at all here.
I'd refactor the queue from the thread first.
But to fix your problem:
struct am_I_alive {
explicit operator bool() const { return m_ptr.lock(); }
private:
std::weak_ptr<void> m_ptr;
};
struct lifetime_tracker {
am_I_alive track_lifetime() {
if (!m_ptr) m_ptr = std::make_shared<bool>(true);
return {m_ptr};
}
lifetime_tracker() = default;
lifetime_tracker(lifetime_tracker const&) {} // do nothing, don't copy
lifetime_tracker& operator=(lifetime_tracker const&){ return *this; }
private:
std::shared_ptr<void> m_ptr;
};
this is a little utility to detect if we have been deleted. It is useful in any code that calls an arbitrary callback whose side effect could include delete(this).
Privately inherit your Queue from it.
Then split popping the task from running it.
std::optional<Task> get_task() {
std::unique_lock<std::mutex> lock(_mutex);
_cv.wait(lock, [this] { return !_running || !_queue.empty(); });
if (!_running && _queue.empty()) {
return {}; // end
}
auto task = _queue.front();
_queue.pop_front();
return task;
}
void sweepQueue() noexcept
{
while (true) {
try {
auto task = get_task();
if (!task) return;
// we are alive here
auto alive = track_lifetime();
try {
(*task).f();
} catch(...) {
std::cerr << "An error occurred while running a task\n";
}
task={};
// we could be deleted here
if (!alive)
return; // this was deleted, get out of here
}
} catch (...) {
std::cerr << "An error occurred while sweeping the queue\n";
}
}
}
and now you are safe.
After that you need to deal with the thread problem.
The thread problem is that you need your code to destroy the thread from within the thread it is running. At the same time, you also need to guarantee that the thread has terminated before main ends.
These are not compatible.
To fix that, you need to create a thread owning pool that doesn't have your "keep alive" semantics, and get your thread from there.
These threads don't delete themselves; instead, they return themselves to that pool for reuse by another client.
At shutdown, those threads are blocked on to ensure you don't have code running elsewhere that hasn't halted before the end of main.
To write such a pool without your inverted dependency mess, split the queue part of your code off. This queue owns no thread.
template<class T>
struct threadsafe_queue {
void push(T);
std::optional<T> pop(); // returns empty if thread is aborted
void abort();
~threadsafe_queue();
private:
std::mutex m;
std::condition_variable v;
std::deque<T> data;
bool aborted = false;
};
then a simple thread pool:
struct thread_pool {
template<class F>
std::future<std::result_of_t<F&()>> enqueue( F&& f );
template<class F>
std::future<std::result_of_t<F&()>> thread_off_now( F&& f ); // starts a thread if there aren't any free
void abort();
void start_thread( std::size_t n = 1 );
std::size_t count_threads() const;
~thread_pool();
private:
threadsafe_queue< std::function<void()> > tasks;
std::vector< std::thread > threads;
static void thread_loop( thread_pool* pool );
};
make a thread pool singleton. Get your threads for your queue from thread_off_now method, guaranteeing you a thread that (when you are done with it) can be recycled, and whose lifetime is handled by someone else.
But really, you should instead be thinking with ownership in mind. The idea that tasks and task queues mutually own each other is a mess.
If someone disposes of a task queue, it is probably a good idea to abandon the tasks instead of persisting it magically and silently.
Which is what my simple thread pool does.

Is it safe to wrap std::async in object

I wrapped std::async in a class similar to this:
class AsyncTask
{
public:
AsyncTask() {}
~AsyncTask()
{
m_shouldTerminate.store(true, std::memory_order::memory_order_release);
}
std::future<int> runAsync()
{
return std::async(std::launch::async, [this]() { threadMain(); return m_result; });
}
private:
void threadMain()
{
for(int i=0; i<std::numeric_limits<int>::max(); ++i)
{
if (m_shouldTerminate.load(std::memory_order::memory_order_acquire))
{
break;
}
// do time consuming calculation but abort if m_shouldTerminate becomes true
m_result += foo([this]() { return m_shouldTerminate.load(std::memory_order::memory_order_acquire); });
}
}
int m_result = 0;
std::atomic<bool> m_shouldTerminate = false;
};
AFAIK std::future::~future blocks if the future was returned from std::async. This would mean that for code like
{
AsyncTask myTask;
myTask.runAsync();
}
bar();
It would block in the temporary future's destructor, then destruct myTask and only then the call to bar() would happen. Considering this it should be ensured that the lifetime of any AsyncTask object exceeds the run time of the task itself and my implementation should be safe.
If AsyncTask is dynamically allocated this guarantee would no longer hold, obviously.
Are my assumptions correct an is my implementation safe? In particular is it possible that an AsyncTask object is destroyed while the async task is still running?

Terminating an std::thread which runs in endless loop

How can I terminate my spun off thread in the destructor of Bar (without having to wait until the thread woke up form its sleep)?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
~Bar() { // terminate thread here}
...
void foo() {
while (true) {
std::this_thread::sleep_for(
std::chrono::seconds(LONG_PERIOD));
//do stuff//
}
}
private:
std::thread thread;
};
You could use a std::condition_variable:
class Bar {
public:
Bar() : t_(&Bar::foo, this) { }
~Bar() {
{
// Lock mutex to avoid race condition (see Mark B comment).
std::unique_lock<std::mutex> lk(m_);
// Update keep_ and notify the thread.
keep_ = false;
} // Unlock the mutex (see std::unique_lock)
cv_.notify_one();
t_.join(); // Wait for the thread to finish
}
void foo() {
std::unique_lock<std::mutex> lk(m_);
while (keep_) {
if (cv_.wait_for(lk, LONG_PERIOD) == std::cv_status::no_timeout) {
continue; // On notify, just continue (keep_ is updated).
}
// Do whatever the thread needs to do...
}
}
private:
bool keep_{true};
std::thread t_;
std::mutex m_;
std::condition_variable cv_;
};
This should give you a global idea of what you may do:
You use an bool to control the loop (with protected read and write access using a std::mutex);
You use an std::condition_variable to wake up the thread to avoid waiting LONG_PERIOD.

detached thread crashing on exiting

I am using a simple thread pool as below-
template<typename T>
class thread_safe_queue // thread safe worker queue.
{
private:
std::atomic<bool> finish;
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
thread_safe_queue() : finish{ false }
{}
~thread_safe_queue()
{}
void setDone()
{
finish.store(true);
data_cond.notify_one();
}
void push(T new_value)
{
std::lock_guard<std::mutex> lk(mut);
data_queue.push(std::move(new_value));
data_cond.notify_one();
}
void wait_and_pop(T& value)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this]
{
return false == data_queue.empty();
});
if (finish.load() == true)
return;
value = std::move(data_queue.front());
data_queue.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
};
//Thread Pool
class ThreadPool
{
private:
std::atomic<bool> done;
unsigned thread_count;
std::vector<std::thread> threads;
public:
explicit ThreadPool(unsigned count = 1);
ThreadPool(const ThreadPool & other) = delete;
ThreadPool& operator = (const ThreadPool & other) = delete;
~ThreadPool()
{
done.store(true);
work_queue.setDone();
// IF thread is NOT marked detached and this is uncommented the worker threads waits infinitely.
//for (auto &th : threads)
//{
// if (th.joinable())
// th.join();
// }
}
void init()
{
try
{
thread_count = std::min(thread_count, std::thread::hardware_concurrency());
for (unsigned i = 0; i < thread_count; ++i)
{
threads.emplace_back(std::move(std::thread(&ThreadPool::workerThread, this)));
threads.back().detach();
// here the problem is if i dont mark it detatched thread infinitely waits for condition.
// if i comment out the detach line and uncomment out comment lines in ~ThreadPool main threads waits infinitely.
}
}
catch (...)
{
done.store(true);
throw;
}
}
void workerThread()
{
while (true)
{
std::function<void()> task;
work_queue.wait_and_pop(task);
if (done == true)
break;
task();
}
}
void submit(std::function<void(void)> fn)
{
work_queue.push(fn);
}
};
The usage is like :
struct start
{
public:
ThreadPool::ThreadPool m_NotifPool;
ThreadPool::ThreadPool m_SnapPool;
start()
{
m_NotifPool.init();
m_SnapPool.init();
}
};
int main()
{
start s;
return 0;
}
I am running this code on visual studio 2013. The problem is when main thread exits. The program crashes. It throws exception.
Please help me with what am i doing wrong? How do i stop the worker thread properly? I have spent quite some time but still figuring out what is the issue.
Thanks for your help in advance.
I am not familiar with threads in c++ but have worked with threading in C. In C what actually happens is when you creates child threads of from the main thread then you have to stop the main thread until the childs finishes. If main exits the threads becomes zombie. I think C don't throw an exception in case of Zombies. And may be you are getting exception because of these zombies only. Try stopping the main until the childs finishes and see if it works.
When main exits, detached threads are allowed to continue running, however, object s is destroyed. So, as your threads attempt to access members of object s, you are running into UB.
See accepted answer of this question for more details about your issue : What happens to a detached thread when main() exits?
A rule of thumb would be not to detach threads from main, but signal thread pool that app is ending and join all thread. Or do as is answered in What happens to a detached thread when main() exits?

Cast to self pointer in static method throws segfault on (derived) method call

I am trying to implement a simple thread starter class. Below you find a Simple base class implementation and 2 derived variations that are supposed to work as starters. The first one throws segfaults at static void* Threaded::run (void* self) sporadically. I suppose this might a pointer issue but I am not able to figure out why?
Does this in Threaded::start point to a wrong address or is there any other issue with my first derivation?
This is how it's used:
Thread thread (ptr_to_some_obj);
thread.start (&this_obj::callback);
thread.detach ();
Simple base class
class Threaded
{
public:
Threaded () {/* empty */}
virtual ~Threaded () {/* empty */}
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool start ()
{
return (pthread_create (&_thread, NULL, run, this) == 0);
}
/** Implement this method in your subclass with the code which allows to gently stop execution. */
virtual void stop () = 0;
/** Will not return until the internal thread has exited. */
void wait ()
{
(void) pthread_join (_thread, NULL);
}
bool detach ()
{
return (pthread_detach (_thread) == 0);
}
protected:
/** Implement this method in your subclass with the code you want your thread to run. */
virtual void run () = 0;
static void* run (void* self)
{
((Threaded*) self) -> run ();
return NULL;
}
pthread_t _thread;
};
Derived class 1 (throws segfault at ((Threaded*) self) -> run (); above)
typedef void (*staticcall)(void*);
class Thread : public Threaded
{
public:
Thread (void* passthru)
:_call (NULL)
{
_passthru = passthru;
}
~Thread () { /* empty */ }
bool start (staticcall call)
{
_call = call;
assert (_call);
return start ();
}
void stop ()
{
// nothing
}
protected:
void run ()
{
(_call) (_passthru);
}
bool start ()
{
return Threaded::start ();
}
private:
Thread () { };
void* _passthru;
staticcall _call;
};
Derived class 2 (works, but i'd rather have Derived class 1 implementation)
typedef void (*staticcall)(void*);
class Thread2 : public Threaded
{
public:
Thread2 (void* passthru)
{
_passthru = passthru;
}
~Thread2 () { /* empty */ }
bool start (staticcall call)
{
_call = call;
assert (_call);
return start ();
}
void stop ()
{
// nothing
}
protected:
void run () { }
static void* run2 (void*)
{
(_call) (_passthru);
return NULL;
}
bool start ()
{
return (pthread_create (&_thread, NULL, run2, NULL) == 0);
}
private:
Thread2 () { };
static void* _passthru;
static staticcall _call;
};
void* Thread2::_passthru;
staticcall Thread2::_call;
As pointed out by molbdnilo:
pthread_create only queues the new thread. There are no guarantees regarding when the thread function will be called, and thread must be alive at that time.
Since I do not want to keep a list of spawned threads around I solved this with the use of pthread_cond_wait and pthread_cond_signal. The spawner will wait for a signal that is emitted by the method that runs in the thread. This way the thread creator won't destroy the thread object before the to-be-threaded method is called.
class ThreadSpawner
{
public:
ThreadSpawner ()
{
pthread_mutex_init (&MtxThreadStarter, 0);
pthread_cond_init (&CondThreadStarter, 0);
}
~ThreadSpawner ()
{
pthread_cond_destroy (&CondThreadStarter);
pthread_mutex_destroy (&MtxThreadStarter);
}
void spawn ()
{
Thread thread (pass_object);
pthread_mutex_lock (&MtxThreadStarter);
if (thread.start (&ThreadSpawner::callback))
{
// wait here for signal
pthread_cond_wait (&CondThreadStarter, &MtxThreadStarter);
thread.detach ();
}
pthread_mutex_unlock (&MtxThreadStarter);
}
static void callback (void* passthru)
{
// send signal to thread spawner
pthread_mutex_lock (&MtxThreadStarter);
pthread_cond_signal (&CondThreadStarter);
pthread_mutex_unlock (&MtxThreadStarter);
// do threaded work
}
private:
static pthread_mutex_t MtxThreadStarter;
static pthread_cond_t CondThreadStarter;
}
pthread_mutex_t ThreadSpawner::MtxThreadStarter = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ThreadSpawner::CondThreadStarter = PTHREAD_COND_INITIALIZER;
Edit: a solution to let a thread execute as a method invokation
Well the solution I thought about in the recent discussion would work if the thread entry point was a simple function.
However, I suppose the idea is more to take advantage of an actual object, so that the thread body is actually an invokation of the body() method.
This is more tricky, since there must be a live instance of the derived class for the whole thread duration, and yet the original instance is likely to get out of scope after a start / detach sequence.
One possible (though somewhat costly) solution is to have the thread body stub create a local copy of the original instance on the stack. So the thread launcher will construct a thread object, and the thread itself will copy it.
With this system, you only need to make sure the original instance will be kept live in the interval between pthread_create and thread activation by the scheduler.
This requires a semaphore (which will be done by hand with a mutex/cond. var. pair for the 1.000.000th time, since bloody C++11 does not have one in store).
To hide this messy code inside the base class, you need to downcast the base pointer into the appropriate subclass type.
I resorted to templating the base class, though there might be smarter solutions out there. I just could not think of any.
To test the solution, I use a counter system that detects whether the original Thread instance has been deleted before the thread stub could make a local copy.
The SYNC compilation flag activates the semaphore. The expected program output is 0->0. If other numbers appear, it means some threads ran on messed-up instances.
I tested it on Ubuntu in a VM, and it seemed to work well enough.
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <thread> // sleep_for
#include <chrono> // milliseconds
#include <pthread.h>
#define SYNC // undefine this to see what happens without synchronization
typedef void *(*tEntryPoint) (void *);
#include <mutex>
#include <condition_variable>
class semaphore {
private:
std::mutex m;
std::condition_variable v;
int c;
public:
semaphore (int count = 0):c(count){}
void V()
{
#ifdef SYNC
std::unique_lock<std::mutex> l(m);
c++;
v.notify_one();
#endif
}
void P()
{
#ifdef SYNC
std::unique_lock<std::mutex> l(m);
while (c == 0) v.wait(l);
c--;
#endif
}
};
template<typename Derived>
class Threaded
{
public:
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool start(void)
{
destructor_guard = new semaphore();
bool res = (pthread_create(&_thread, NULL, (tEntryPoint)entry_point, this) == 0);
if (res) destructor_guard->P(); // wait fot thread to start execution
delete destructor_guard;
return res;
}
/** This optional method will be executed after the thread main body */
virtual void stop() {}
/** Will not return until the internal thread has exited. */
void wait()
{
(void)pthread_join(_thread, NULL);
}
/** Will let the underlying task run independently */
bool detach()
{
return (pthread_detach(_thread) == 0);
}
private:
static void * entry_point(Derived * self)
{
Derived local_self = *self;
local_self.destructor_guard->V(); // original can be deleted
local_self.body();
local_self.stop();
return NULL;
}
pthread_t _thread;
semaphore* destructor_guard;
};
#define NUM_THREADS 9
#define REPEAT 3000
static int signature[NUM_THREADS + 1] = { 0, };
class Thread : public Threaded<Thread>
{
unsigned id;
public:
Thread(unsigned id) : id(id) {}
~Thread() { id = 0; }
void body(void)
{
signature[id%(NUM_THREADS+1)]++;
}
void stop(void)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
signature[id%(NUM_THREADS+1)]++;
}
};
void launch_a_thread(int id)
{
Thread thread (id);
if (thread.start())
{
// thread.wait();
thread.detach();
}
}
int main(void)
{
for (unsigned i = 0; i != REPEAT*NUM_THREADS; i++) launch_a_thread(1+i%NUM_THREADS);
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // leave enough time for free running threads to terminate
for (int i = 0 ; i <= NUM_THREADS ; i++) if (signature[i] != 2*REPEAT) printf ("%d -> %d\n", i, signature[i]);
return 0;
}