Calling detach() at the end of the thread - c++

I have a working thread similar to the following code. In begin_work, it will check whether the working thread is executing before creating a new working thread. However, begin_work will never create the next working thread when the current thread is exited until I call end_work.
I have tried to call detach at the end of the thread and it works fine. Is it safe to call detach at the end of the thread? Or, how can I do to safely create the next working thread without calling end_work before calling begin_work?
class thread_worker {
private:
std::thread worker;
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (!worker.joinable()) {
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
if (exit not by notify) {
worker.detach(); // can I call detach?
}
}
void end_work() {
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};
Edit:
My purpose is to call begin_work without block. If there is one working thread on execution, then the function will return directly or returns an is_working error. Otherwise, create a new working thread seamlessly.
Since std::thread::joinable() always returns true until join or detach is called. As a result, the future call of begin_work will never create the new working thread even though the current working thread has exited.
Therefore, I need a mechanism to automatically detach at the end of the thread.

I have tried to call detach at the end of the thread and it works fine
There's data race in the access to worker - it's undefined behaviour. When begin_work tests worker.joinable(), do_work might be detaching it at the same time (the call to worker.detach()).
You can instead detach the immediately when creating it:
worker = std::thread { &thread_worker::do_work, this };
worker.detach();
However, this can leave multiple threads running at the same time, which contradicts your requirement of running one worker thread at a time (but why only one? that just makes threading pointless).
Instead you can do:
void begin_work() {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
which ensures the previous thread completed.
Based on yuor edit, you only need to check whether you can join without wait - that seems to be reason you want to detach. You can instead do that with an atomic flag. Basically, you just to take care of the data race noted above.
class thread_worker {
private:
std::thread worker;
std::atomic_bool w_done {true};
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (w_done) {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
w_done = true;
}
void end_work() {
w_done = false;
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};

Related

Is it ok/safe to delete a class that contains running threads when I want the threads to terminate?

Here is a quick example:
class worker
{
std::thread thread1;
std::thread thread2;
worker(){}
start()
{
thread1 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread1.deteach();
thread2 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread2.deteach();
}
~worker()
{
// Ignore this part! - as per Richard's comment :)
//thread1.join(); // <-- do I need this at all?
//thread2.join(); // <-- do I need this at all?
}
}
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker;
}
Create the worker
Start the threads which last for 50 seconds
After 1 second delete the worker (calls destructor)
In worker destructor I re-join the threads (probably should check if they are joinable first?) - not really sure I need to do this.
Then worker is destroyed
I had a look at this question: how-do-i-terminate-a-thread-in-c11 which suggests there is no c11 portable way to terminate the threads.
Questions:
Are the threads destroyed completely (no dregs/leaks left)?
If "yes" do I need to re-join the threads in order for them to be destroyed? EDIT - Richard pointed out this is N/A
Is this a sensible approach?
As already stated in comments, you cannot join a detached thread.
Detached threads are meant to run independently. In general, it is a bad idea to detach a thread owned by a class.
I would suggest using a boolean to control the lifecycle of your thread.
For example, you could do something like this:
class worker
{
private:
std::thread thread1;
std::atomic<bool> thread1ShouldRun;
std::thread thread2;
std::atomic<bool> thread2ShouldRun;
void workerFunc1() {
bool threadWorkIsDone = false;
while (thread1ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread1ShouldRun.store(false);
}
}
void workerFunc2() {
bool threadWorkIsDone = false;
while (thread2ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread2ShouldRun.store(false);
}
}
public:
worker() {}
void start()
{
thread1ShouldRun.store(true);
thread1 = std::thread(&worker::workerFunc1, this);
thread2ShouldRun.store(true);
thread2 = std::thread(&worker::workerFunc2, this);
}
~worker()
{
thread1ShouldRun.store(false);
// Protection in case you create a worker that you delete and never call start()
if (thread1.joinable())
thread1.join();
thread2ShouldRun.store(false);
if (thread2.joinable())
thread2.join();
}
};
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker; // Threads will be joined here
}
Yes, the threads are completely destroyed by the std::thread dtor if they are still joinable (running and not detached).
That's not good news though, as std::terminate() will be called, killing the whole process.
In general, just terminating is only sensible to avoid further damage from an unexpected state, or if the application was built for harmless termination at that exact point.

Terminate current thread in destructor

In a project we're creating multiple statemachines in a wrapper-class. Each wrapper runs in it's own thread. When the jobs is done, the wrapper-class destructor is being called, and in there we would like to stop the thread.
Though if we're using thread.join(), we get a deadlock (since it tries to join itself). We could somehow signal another thread, but that seems a bit messy.
Is there any way to properly terminate the thread in which a class is running in, upon object destruction?
thread.join() does not stop a thread. It waits for the thread to finish and then returns. In order to stop a thread you have to have some way of telling the thread to stop, and the thread has to check to see whether it's time to stop. One way to do that is with an atomic bool:
class my_thread {
public:
my_thread() : done(false) { }
~my_thread() { done = true; thr.join(); }
void run() { thread th(&my_thread::do_it, this); swap(th, thr); }
private:
void do_it() { while (!done) { /* ... */ } }
std::thread thr;
std::atomic<bool> done;
};
That's off the top of my head; not compiled, not tested.

C++ Thread access issue with class member variables

After using threads for a while, I got into a situation where I needed a thread to run forever until a a function (or any sort of event) was called. To do this I created a bool value to control a while loop inside the function that was executed by the thread, but I quickly noticed that external variables are not updated after a thread starts running, causing the thread to never stop when it was asked to.
Heres some simple code to represent the issue:
#include <cstdio>
#include <thread>
#include <chrono>
class A {
public:
A();
void startThread();
void endThread();
private:
void threadCall();
bool active;
};
int main() {
A threadThing;
threadThing.startThread();
printf("[M] Thread Created\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
threadThing.endThread();
printf("[M] Thread Killed\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
A::A() {
active = false;
}
void A::startThread() {
active = true;
std::thread AThread(&A::threadCall, *this);
AThread.detach();
}
void A::endThread() {
active = false;
}
void A::threadCall() {
printf("[T] Thread Started\n");
while (active) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}
The expected result of this would be that the main function starts the thread, the thread says it started, then 4 seconds later the thread is killed and the thread says it ended, when in reality the thread never says it ends. Is there a way to let the thread access the 'active' variable, or is my approach to this problem incorrect altogether? (Side note, I did try to figure this out on my own but only got stuff like local thread storage which seems like its only for storage inside of threads, not access to the outside but I could be wrong)
The problem is with the constructor of std::thread, it copies/moves by default.
std::thread AThread(&A::threadCall, *this);
this copies the object into the new thread, so checking the active variable in the new object has no effect.
you can remove the *
std::thread AThread(&A::threadCall, this);
you pass the object pointer into the new thread, it will call like the method like this(*this).threadCall().
Edit: as the comments say, this is not guarantee to be thread safe, you need to use std::atomic<bool> to be safe.
What you need to do is pass an A class pointer as an argument to your function that is your thread.
void A::startThread()
{
active = true;
std::thread AThread(threadCall, this);
AThread.detach();
}
void A::threadCall(A *aClass)
{
printf("[T] Thread Started\n");
while (aClass->active)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}

Deleting boost::thread descendant

I am trying to write a class that would run a thread upon its object creation and stop the thread once the object gets deleted.
class MyThread : public boost::thread {
public:
MyThread() : bAlive(true) {
boost::thread(&MyThread::ThreadFunction,this);
}
~MyThread() {
{
boost::unique_lock<boost::mutex> lock(Mutex);
bAlive=false;
}
ConditionVariable.notify_one();
join();
}
private:
volatile bool bAlive;
boost::mutex Mutex;
boost::condition_variable ConditionVariable;
void ThreadFunction() {
boost::unique_lock<boost::mutex> lock(Mutex);
while(bAlive) {
ConditionVariable.timed_wait(lock,boost::get_system_time()+ boost::posix_time::milliseconds(MAX_IDLE));
/*******************************************
* Here goes some code executed by a thread *
*******************************************/
}
}
};
Theoretically, I want to wake the thread up instantly as soon as it needs to be finished, so I had to use timed_wait instead of Sleep.
This works fine until I try to delete an object of this class. In most cases, it deletes normally, but occasionally it causes an error either in condition_variable.hpp, thread_primitives.hpp or crtexe.c. Sometimes I am notified that "Free Heap block 3da7a8 modified at 3da804 after it was freed", and sometimes I'm not. And yes, I'm aware of the spurious wakeups of timed_wait, in this case it's not critical.
Can you please point me to the source of my problem? What am I doing wrong?
I see what you're trying to do but it doesn't work as you expect:
MyThread foo;
default constructs a boost::thread (because MyThread is derived from boost::thread).
The default constructor creates a boost::thread instance that refers to Not-a-Thread.
MyThread() {
boost::thread(&MyThread::ThreadFunction,this);
}
is actually creating a different thread and you're ignoring the returned object (the valid thread).
~MyThread() {
// ...
join();
}
is then trying to join the default constructed thread (which throws an exception inside the destructor) and you never join the thread that actually does the work.
First of all, don't derive from boost::thread. Create a member variable instead:
class MyThread {
// ...
private:
// ...
boost::thread _thread;
};
In the constructor, create and assign a thread to that member variable:
MyThread() {
_thread = boost::thread(&MyThread::ThreadFunction,this);
}
and call its join() in your destructor.
~MyThread() {
// ...
_thread.join();
}
That should fix your problem.
However, if you simply want to exit the thread when your object is destroyed (and don't have to wake it up while its running), you can use a different approach. Remove the mutex and the condition variable and use interrupt instead. This will cause sleep() to throw an exception so you have to catch it:
void ThreadFunction() {
try {
for(;;) {
boost::this_thread::sleep(boost::posix_time::milliseconds(MAX_IDLE));
// Here goes some code executed by a thread
}
} catch( const boost::thread_interrupted& e ) {
// ignore exception: thread interrupted, exit function
}
}
This will instantly exit the ThreadFunction when the thread is interrupted. If you don't need the thread to sleep every cycle, you can replace it with boost::this_thread::interruption_point(). This will just throw an exception if the thread is interrupted.
Now you can simply interrupt the thread in the destructor:
MyThread::~MyThread() {
_thread.interrupt();
_thread.join();
}

Implement a multithreading environment

I want to implement a multithreading environment using Qt4. The idea is as follows in c++-alike pseudo-code:
class Thread : public QThread {
QList<SubThread*> threads_;
public:
void run() {
foreach(SubThread* thread : threads) {
thread.start();
}
foreach(SubThread* thread : threads) {
thread.wait();
}
}
void abort() {
foreach(SubThread* thread : threads) {
thread.cancel();
}
}
public slots:
// This method is called from the main-thread
// (sometimes via some signal-slot-connection)
void changeSomeSettings() {
abort();
// change settings
start();
}
}
class SubThread : public QThread {
bool isCancelled_;
public:
void run() {
while(!isCancelled or task completed) {
// something that takes some time...
}
}
void cancel() {
if(isRunning() {
isCancelled_ = true;
}
}
}
The purpose is that the slot changeSomeSettings() kills all running threads, commits its changes and restarts it. What I want to achieve is that once this method has been started, it calls "abort" and then waits until all threads have terminated. Using mutexes in a wrong way:
void Thread::changeSomeSettings() {
mutex1.lock();
abort();
mutex2.lock();
start();
mutex1.unlock();
}
void Thread::run() {
foreach(Thread* thread : threads) {
thread.start();
}
foreach(Thread* thread : threads) {
thread.wait();
}
mutex2.unlock();
}
This actually works in Qt under MacOSX, yet according to the documentation mutex2 must be unlocked in the same thread (and in Windows I get an error). What is the best way to achieve my goal without running into racing conditions and deadlocks? Is there a better design than the one I have proposed here?
You probably want to use a condition variable instead of a mutex for this situation. A condition variable is a way for one thread to signal another. QT's implementation appears to be the QTWaitCondition:
I might have the child thread's periodically check the state of the condition variable. This can be done with QTWaitCondition::wait() with a short/0 timeout. If it is being signaled, then lock a shared memory area containing updated data and access the data that needs to be updated. Then that thread can safely restart itself accordingly.
It's usually not a good idea to just abort a thread. You may end up leaking memory/resources/handles/locks/etc. You don't know where that thread is in it's call stack, and there may be no guarantees that the stack will be "unwound" for you and all destructors are called. This is another reason for the child threads checking a condition variable periodically for updated data and having them restart themselves safely with the new data.