simple question about standard c++ multithreading [duplicate] - c++

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.

Related

std::async vs. thread [duplicate]

This question already has answers here:
When to use std::async vs std::threads?
(5 answers)
Closed 1 year ago.
I am trying to understand how exactly async differs from using threads. On a conceptual level, I thought multithreading was by definition asynchronous, because you are doing context switches between threads for things like I/O.
But it seems that even for instances like single-threaded applications, just adding threads would be the same as using async. For example:
#include <iostream> // std::cout
#include <future> // std::async, std::future
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
std::cout << "Calculating. Please, wait...\n";
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call is_prime(313222313) asynchronously:
std::future<bool> fut = std::async (is_prime,313222313);
std::cout << "Checking whether 313222313 is prime.\n";
// ...
bool ret = fut.get(); // waits for is_prime to return
if (ret) std::cout << "It is prime!\n";
else std::cout << "It is not prime.\n";
return 0;
}
Why can't I just create a thread to call is_prime that writes to some variable, and then call join() before I print that variable? If I can do this, what really is the benefit of using async? Some specific examples would be very helpful.
This is not C++ specific, so I try to be a little bit generic. I'm sure there are C++ specific quirks as well.
Generally speaking, yes. You could just create a variable for the output, start a thread, give the address of the variable to the thread and later .join the thread and access the variable after the thread wrote to it. That works. Nothing wrong with it. We did that for many years.
But as the program gets more complicated, this gets more and more messy. More and more thread to keep running, more and more variables to keep in mind when and how to access them safely. Can I print i here, or do I need to .join a specific thread first? Who knows.
Futures (or Promises or Tasks) and async/await is a pattern many languages use nowadays under those or very similar names. They don't do anything we could not do before, but they make it a lot easier to maintain when the program grows and is no longer this one page example program that everybody can read on one screen.

How to terminate a thread safely? (with the usage of pointer) 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;

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;
}

Reusing a thread - boost vs std thread behaviour

I seem to be getting different thread object assignment behaviour between boost and std threads. If I use boost threads, a thread member variable can be reassigned and the thread recreated. If I use std threads, I get a runtime error terminate called without an active exception.
Here is the code in question (run, then replace std:: with boost::)
class ThreadTest
{
private:
std::thread mythread;
std::atomic<bool> running_;
int doSomeWork(){
int i=0;
cout << "starting" << endl;
while(running_){
cout << "working" << endl;
std::this_thread::sleep_for (std::chrono::seconds(1));
if (i>3){ break; } else { i++; }
}
running_ = false;
}
public:
void runThread(){
running_ = true;
mythread = std::thread(&ThreadTest::doSomeWork, this);
}
void joinThread(){
mythread.join();
}
};
int main(){
ThreadTest test;
test.runThread();
std::this_thread::sleep_for (std::chrono::seconds(10));
test.runThread();
test.joinThread();
return 0;
}
Output for boost::
starting
working
working
working
working
working
starting
working
working
working
working
working
Output for std::
starting
working
working
working
working
working
terminate called without an active exception
Aborted (core dumped)
This particular piece of code is used in a library which doesn't seem to have boost as a dependency. I would like to keep it that way, so is there a way to get the boost 'reassignment' behaviour using std threads?
EDIT - SOLUTION
I added an std::atomic<bool> threadInitialized_; to the class which is set to true in the thread function doSomeWork(). My runThread() method becomes:
void runThread(){
if(threadInitialized_)
mythread.join();
running_ = true;
mythread = std::thread(&ThreadTest::doSomeWork, this);
}
I am aware this will block the main thread until the spawned thread is done.
Typically, as correctly pointed out above, all (joinable) threads need to be joined or detached before their object is destroyed.
Now, one (of many) differences between boost threads and std::thread is that Boost threads detach themselves inside their destructor which std::thread's do not; your incorrect usage of std::thread therefore correctly fires terminate().
PS: Do NOT (!!) believe the other commentors above that std::threads and boost::thread should behave "the same" - this is just not true!
From std::thread::operator = ()
"If [the thread object] is joinable, terminate() is called."
While using boost::thread, if you don't explicitly call join() or detach() then the boost::thread destructor and assignment operator will call detach() on the thread object being destroyed/assigned to respectively.
With a C++11 std::thread object, this will result in a call to std::terminate() and abort the application. In this case you have to call detach() or join() manually.

Output of multiple thread executions only happens once? [duplicate]

This question already has answers here:
C++ std::vector of independent std::threads
(4 answers)
Closed 4 years ago.
#include <iostream>
#include <thread>
void func() {
std::cout << "Hello";
}
int main() {
std::vector<std::thread> threads;
int n = 100;
for (int i = 0; i < n; i++) {
std::cout << "executing thread" << std::endl;
threads.push_back(std::thread(func));
}
}
My program prints "executing thread" once and it ends. What is the cause?
After this loop completes the destructor of std::vector<std::thread> is invoked. std::thread destructor calls std::terminate if the thread was neither detached nor joined, like in your case.
To fix that, add the following after the loop:
for(auto& thread : threads)
thread.join();
Make sure you join the threads to wait for them all to complete:
for (auto &thread : threads) {
thread.join();
}
If the program continues after this point and doesn't exit immediately, flush the output since it may be buffered:
std::cout << std::flush;
Even if you don't join, it should still print "executing thread" 100 times.
Perhaps the problem is using "endl" instead of "std::endl"
Once the loop creating the threads is done, your program continues. And it continues to leave the main function which causes all variables defined inside the main function to go out of scope and their life-time ending. This leads to the destruction of the objects, including the vector which then leads to all the thread object in the vector being destructed.
And as noted by others, the destruction of a thread object will lead to program termination if the thread is not joined or detached.
While the other answers tell you to join the threads (which IMO is the recommended solution here) there is another possible solution: To detach the threads.
While this will lead to the std::terminate function to be called and prematurely terminate your program, this will lead to another problem, as leaving the main function ends the process and all its threads.
If you for some reason what your threads to continue to live on after the main function exits, you need to detach the threads and exit the "main thread" using an operating-system specific function. This will leave the process running with all your created threads still chugging along.