How to terminate a thread safely? (with the usage of pointer) c++ - c++

I am currently learning multithreading in c++11 and I am confused with the way to terminate a thread safely.
In c++, I know the way to create threads and use thread.join() to safely ensure main() to wait for all threads to finish before quitting itself.
However, I found that some multithread codes implemented via pointers are able to run even without using thread.join().
class Greating
{
public:
Greating(const int& _i):i_(_i){}
~Greating(){}
int i_;
void say()
{
std::cout << "Hello World" << i_ << std::endl;
}
};
int main(){
Greating greating1(1);
Greating greating2(2);
std::thread t1(&Greating::say, greating1);
std::thread t2(&Greating::say, greating2);
return 0;
}
The code shown above will absolutely report the error "terminate called without an active exception
Aborted (core dumped)", because I did not use t1.join() and t2.join().
However, I found in some codes when they use the pointer to manage the thread, this does not become a problem, as shown below.
class Greating
{
public:
Greating(const int& _i):i_(_i){}
~Greating(){}
int i_;
void say()
{
std::cout << "Hello World" << i_ << std::endl;
}
};
int main(){
Greating greating1(1);
Greating greating2(2);
std::thread* tt1 = new std::thread(&Greating::say, greating1);
std::thread* tt2 = new std::thread(&Greating::say, greating2);
return 0;
}
The output is:
Hello WorldHello World12
Hello World12
There is no error reported. This made me very confused.
So my question is:
Why when we use pointer to manage the thread, we could not use the function thread.join()?
How to correctly terminate a thread? (probably wait for the callable function to finish?)
Thanks very much!

When creating objects with dynamic allocation, you have to deallocate the memory with operator delete so it calls appropriate destructor.
In the first example, two std::thread objects are created. At the end of main function, the destructor std::thread::~thread is called. Since the threads are not joined, the destructor reports an error.
On the other hand, in the second example, you called operator new so you create objects with dynamic allocation. But, you didn't call operator delete, so the destructor is not called. That is, the program didn't check whether the threads are joined.
Therefore, the only way to correctly terminate a thread is to call std::thread::join. If you want to use pointers, you have to do as following:
std::thread *th = new std::thread(foo);
...
th->join();
delete th;

Related

c++ Thread handling in class

I would like to create a object in which I can start a thread and have a function to join withe the created thread. Everything insight the object, so that the thread is a private component of the object.
I have tried a bit and got those Results. Could some of you explain me what I have done wrong, and why I get this errors?
A.h
#include <thread>
class A{
std::thread a;
public:
//this should be a void function
std::thread startThread();
void join();
void (*threadFunction)() = nullptr;
};
and the A.cpp
#include "../header/A.h"
std::thread A::startThread()
{
std::thread a((*threadFunction));
return a;
}
void A::join()
{
a.join();
}
main.cpp
void newFunc(){
std::cout<<"I'm a thread"<<std::endl;
}
int main(){
auto object = new A();
object->threadFunction = &newFunc;
//Version 1) Error "terminate called without an active exception"
object->startThread();
object->join();
/*
Version 2) terminate called after throwing an instance of 'std::system_error'
I'm a thread
what(): Invalid argument
*/
auto value = object->startThread();
object->join();
//Version 3) I'm a thread
auto value = object->startThread();
value.join();
}
I don't see the difference. I have stored the thread in the object, so it is not lost... and when I store the return value and don't use it, its almost fine... but not really ... and directly join() is perfect ... I don't get it :D
Please help me
std::thread A::startThread()
{
std::thread a((*threadFunction));
return a;
}
Does not interact with the member variable a, but it creates a new local variable std::thread object and then moves it to the result (unless the move is optimized out). The thread A::a always remains the default constructed one. A default constructed thread object is non-joinable, i.e. throws an exception on the call of std::thread::join. The only thread join can be called for without causing an exception is the thread object returned from the function.
If you don't join the returned thread and its destructor runs (happens when you drop the temporary thread object returned (Version 1)), std::terminate shuts your program down.
To make this work you need to move assign a newly created thread to the member variable and not return the thread object or just return a reference to it:
void A::startThread()
{
a = std::thread(threadFunction);
}
or
std::thread& A::startThread()
{
a = std::thread(threadFunction);
return a;
}
I wouldn't recommend the second alternative, it drastically reduces your ability to enforce class invariants with regards to the thread lifecycle.

How can I pass an object's member variable (field) as a reference to a thread safely?

Let's say I start a new thread from a classmethod and pass "this" as a parameter to the lambda of the new thread. If the object is destroyed before the thread uses something from "this", then it's probably undefined behavior.
As a simple example:
#include <thread>
#include <iostream>
class Foo
{
public:
Foo() : m_bar{123} {}
void test_1()
{
std::thread thd = std::thread{[this]()
{
std::cout << m_bar << std::endl;
}};
thd.detach();
}
void test_2()
{
test_2(m_bar);
}
void test_2(int & bar)
{
std::thread thd = std::thread{[this, & bar]()
{
std::cout << bar << std::endl;
}};
thd.detach();
}
private:
int m_bar;
};
int main()
{
// 1)
std::thread thd_outer = std::thread{[]()
{
Foo foo;
foo.test_1();
}};
thd_outer.detach();
// 2)
{
Foo foo;
foo.test_1();
}
std::cin.get();
}
The outcomes
(For the original project, I have to use VS19, so the exception messages are originally coming from that IDE.)
Starting from thd_outer, test_1 and test_2 are either throwing an exception (Exception thrown: read access violation.) or printing 0 (instead of 123).
Without thd_outer they seem correct.
I've tried the same code with GCC under Linux, and they always print 123.
Which one is the correct behavior? I think it is UB, and in that case all are "correct". If it's not undefined, then why are they different?
I would expect 123 or garbage always because either the object is still valid (123) or was valid but destroyed and a) the memory is not reused yet (123) or reused (garbage). An exception is reasonable but what exactly is throwing it (VS only)?
I've came up with a possible solution to the problem:
class Foo2
{
public:
Foo2() : m_bar{123} {}
~Foo2()
{
for (std::thread & thd : threads)
{
try
{
thd.join();
}
catch (const std::system_error & e)
{
// handling
}
}
}
void test_1()
{
std::thread thd = std::thread{[this]()
{
std::cout << m_bar << std::endl;
}};
threads.push_back(std::move(thd));
}
private:
int m_bar;
std::vector<std::thread> threads;
};
Is it a safe solution, without undefined behaviors? Seems like it's working. Is there a better and/or more "standardized" way?
Forget about member variables or classes. The question then is, how do I make sure that a thread does not use a reference to an object that has been destroyed. Two approaches exist that both effectively ensure that the thread ends before the object is destroyed plus a third one that's more complicated.
Extend the object lifetime to that of the thread. The easiest way is to use dynamic allocation of the object. In addition, to avoid memory leaks, use smart pointers like std::shared_ptr.
Limit the thread runtime to that of the object. Before destroying the object, simply join the thread.
Tell the thread to let go of the object before destroying it. I'll only sketch this, because its the most complicated way, but if you somehow tell the thread that it must not use the object any more, you can then destroy the object without adverse side effects.
That said, one advise: You are sharing an object between (at least) two threads. Accessing it requires synchronization, which is a complex topic in and of itself.

simple question about standard c++ multithreading [duplicate]

This question already has answers here:
When should I use std::thread::detach?
(6 answers)
Closed 2 years ago.
hi i am newbie learning c++ multithreading
this ques may look stupid but just curious why it's happening
would be amazing if somebody points out what is going on underhood
so,
class background_task
{
public:
void operator()() const
{
for (int i = 0; i < 1000; ++i)
std::cout << "Hello world " << i << std::endl;
}
};
void Func()
{
for(int i=0; i<1000;++i)
std::cout << "Hello world " <<i<< std::endl;
};
void main()
{
background_task bt;
std::thread t(bt);
//t.detach();
}
it gives me the runtime error saying "abort() has been called"
and with detach() it works just fine.
the either case, the new thread execute the loop all the way to end(1000times)
i just guess the error happens because there's additional thread going when runtime thread exits.
but even when i called detach(), there's still additional thread as well and output no error in this case.
i guess, in the destructor of std::thread, it checked like assert(!joinable()) or am i missing something else?
You need to either detach or join std::thread objects before they get destroyed. This is part of the API and documented in the destructor:
std::thread::~thread
Destroys the thread object.
If *this has an associated thread (joinable() == true), std::terminate() is called.
What you usually want is to join the thread, which blocks the current thread until the other thread has finished.
If you want a thread that automatically joins on destruction, you can use C++20's std::jthread instead.

Start thread within member function using std::thread & std::bind

I have few queries with respect to below code snapshot.
1) With respect to pthread_create(), assume Thread_1 creates Thread_2. To my understanding Thread_1 can exit without join, but still Thread_2 will keep running. Where as in below example without join() I am not able to run thread and I am seeing exceptions.
2) In few examples I am seeing thread creation without thread object as below. But when I do the same, code is terminated.
std::thread(&Task::executeThread, this);
I am compiling with below command.
g++ filename.cpp -std=c++11 -lpthread
But still it terminate with exception. Is this right way of creating thread or is there any different version of C++ (In my project already they are compiling but not sure about the version).
3) In few examples of my project code, I am seeing below way of creating thread. But I am not able to execute with below example.
std::thread( std::bind(&Task::executeThread, this) );
Below is my code snapshot.
#include <iostream>
#include <thread>
class Task
{
public:
void executeThread(void)
{
for(int i = 0; i < 5; i++)
{
std::cout << " :: " << i << std::endl;
}
}
void startThread(void);
};
void Task::startThread(void)
{
std::cout << "\nthis: " << this << std::endl;
#if 1
std::thread th(&Task::executeThread, this);
th.join(); // Without this join() or while(1) loop, thread will terminate
//while(1);
#elif 0
std::thread(&Task::executeThread, this); // Thread creation without thread object
#else
std::thread( std::bind(&Task::executeThread, this) );
while(1);
#endif
}
int main()
{
Task* taskPtr = new Task();
std::cout << "\ntaskPtr: " << taskPtr << std::endl;
taskPtr->startThread();
delete taskPtr;
return 0;
}
Thanks & Regards
Vishnu Beema
std::thread(&Task::executeThread, this); statement creates and destroys a thread object. The destructor of std::thread invokes std::terminate when the thread wasn't joined or detached (like in your statement).
There is no good reason to use std::bind in C++11 because lambdas are better in terms of space and speed.
When building multi-threaded code you need to specify -pthread option when both compiling and linking. Linker option -lpthread is both inadequate and unnecessary.
By design, you need to join all the threads you spawned, or detach them. See e.g. SO question on join/detach
See also cppreference, detach
Note also important caveats if main() exits while detached threads are still running
I also 100% agree with the comment in the other answer about preferring lambdas to bind.
Finally, do not fall for the temptation to do pthread_cancel on a thread in C++. See e.g pthread_cancel considered harmful
In C++ objects have a lifetime. This is a bit different then dealing with handles in C. In C++ if you create an object on the stack in one scope it will be destroyed if you exit that scope. There are some exception to these rule like std::move, but as a rule of thumb you own the lifetime of an object.
This ties into the same answer as above. When you called std::thread(&Task::executeThread, this); you were actually invoking the thread constructor. This is the start of the thread life and the object lifetime. Notice that you created this object on the stack. If you leave the scope { .. yourcode .. } the DTor will be called. Since you have done this before std::move, join or detatch then std::terminate() is called which is raising the exception.
You can create a thread that way. If you look at the linked documentation for std::thread::thread (constructor) there is an example of an object foo being created the same way. What errors are you receiving?
Relevant Documentation:
a. std::thread::~thread()
b. std::thread::thread
c. Lifetime in C++
I personally would recommend understanding the lifetime of objects in a C++. In short all objects start their lifetime when their constructor is invoked. When they are killed (as in out of scope) their destructor is called. The compiler handles this for you so if you're coming from C its a new concept.
Thank you all for your inputs. I missed thread object as part of thread creation. Because of this though compiling, I am getting exceptions. Below is my updated code. All three scenarios are working fine.
#include <iostream>
#include <thread>
class Task
{
public:
void executeThread(std::string command)
{
for(int i = 0; i < 5; i++)
{
std::cout << command << " :: " << i << std::endl;
}
}
void startThread(void);
std::thread th2;
std::thread th3;
};
void Task::startThread(void)
{
std::cout << "\nthis: " << this << std::endl;
#if 0
std::thread th1(&Task::executeThread, this, "Thread1");
th1.join(); // Without join(), thread will terminate
#elif 0
th2 = std::thread(&Task::executeThread, this, "Thread2");
th2.join();
#else
th3 = std::thread( std::bind(&Task::executeThread, this, "Thread3") );
th3.join();
#endif
}
int main()
{
Task* taskPtr = new Task();
std::cout << "\ntaskPtr: " << taskPtr << std::endl;
taskPtr->startThread();
delete taskPtr;
return 0;
}

QNX c++ thread question

I have a question concerning this code which I want to run on QNX:
class ConcreteThread : public Thread
{
public:
ConcreteThread(int test)
{
testNumber = test;
}
void *start_routine()
{
for(int i = 0; i < 10; i++)
{
sleep(1);
cout << testNumber << endl;
}
}
private:
int testNumber;
};
class Thread
{
public:
Thread(){};
int Create()
{
pthread_t m_id;
return pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this);
}
protected:
virtual void *start_routine() = 0;
private:
static void *start_routine_trampoline(void *p)
{
Thread *pThis = (Thread *)p;
return pThis->start_routine();
}
};
Now, when I run this code without the sleep in *start_routine, it will simply print the number 10 times, before continuing on to the next line of code (sequential instead of parallel). However, when I use a sleep like in the code, it doesn't print any numbers at all and simply goes on to the next line of code. Why doesn't sleep work and how can I make a thread like this work, instead of running sequential?
Note 1: If you only have 1 processor the code can only be done sequentially no matter how many threads you create. Each thread is given a slice of processor time before it is swapped out for the next threads.
Note 2: If the main thread exits pthreads will kill all child threads before they have a chance to execute.
Now to answer you questions:
Without the sleep. The thread once started has enough time in the single slice it was given to execute the loop 10 times completely.
With the sleep: Your worker thread is going to sleep for a full second. So your main thread has time to do a lot of work. If the main thread exits in this time the worker will be killed.
I would make the following changes:
// Remove the Create() method
// Put thread creation in the constructor.
// Make the thread variable part of the object
pthread_t m_id;
Thread()
{
if (pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this) != 0)
{
throw std::runtime_error("Thread was not created");
}
}
// Make sure the destructor waits for the thread to exit.
~Thread()
{
pthread_join(m_id);
}
If you go and look at boost threading library. you will find that all the little mistakes like this have already been taken care of; Thus making threading easier to use.
Also note. That using a static may work but it is non portable. This is because pthread's is a C library and is thus expecting a function pointer with a C ABI. You are just getting lucky for your platform here. You need to define this as a function and declare the ABI by using extern "C"
// This needs to be a standard function with C Interface.
extern "C" void *start_routine_trampoline(void *p)
{
}
Try to make the pthread_t id a class member instead of a function local variable. That way the caller can pthread_join it.
Not doing this is technically a resource leak (unless the thread is specifically not joinable). And joining will avoid the issue that Martin York described.
From man pthread_join:
The joined thread th must be in the joinable state: it must not have
been detached using pthread_detach(3) or the PTHREAD_CREATE_DETACHED
attribute to pthread_create(3).
When a joinable thread terminates, its memory resources (thread
descriptor and stack) are not deallocated until another thread performs
pthread_join on it. Therefore, pthread_join must be called once for
each joinable thread created to avoid memory leaks.
Going off on a tangent here... With respect to Martin York's post:
Also note. That using a static may work but it is non portable. This is because pthread's is a C library and is thus expecting a function pointer with a C ABI. You are just getting lucky for your platform here. You need to define this as a function and declare the ABI by using extern "C" // This needs to be a standard function with C Interface. extern "C" void * start_routine_trampoline(void * p) {...}
I'm not so sure about that...
(1) C++ was designed to be as compatible with C as possible. There are a few differences... But I was under the impression that extern "C" was used mostly to circumvent the name-mangling required to implement C++ function overloading.
(2) It seems like, once you have the function pointer, the calling conventions (what gets pushed on the stack to make the function call) just has to be the same between C & C++. Otherwise, how would function pointers work?
E.g.:
C code:
void bar( int i ) { printf( "bar %d\n", i ); }
C++ code:
class Foo
{
public:
static void foo( int i ) { cout << "foo " << i << endl; }
};
extern "C" { void bar(int); }
int main()
{
void (*p)(int);
p = & Foo::foo;
(*p)(1);
p = & bar;
(*p)(2);
}