std::thread created as detach thread terminates when main exits [duplicate] - c++

This question already has answers here:
How does thread::detach() work in C++11?
(2 answers)
What happens to a detached thread when main() exits?
(7 answers)
Closed 1 year ago.
I am writing the following c++ code to create a detach thread :
void threadF() {
ofstream f("data") ;
for(int i=1; i<=5; i++) {
f<<"t1:::"<<i<<"\n" ;
f.flush() ;
sleep(1) ;
}
f.close() ;
}
int main() {
thread t1(threadF) ;
cout<<"main #1\n" ;
sleep(2) ;
t1.detach() ;
cout<<"main #2\n" ;
}
When I run this code, I have the following observations :
main exits after 2 secs (as expected)
the detach child thread also seems to be running only for 2secs because the output data file contains only 2 lines.
I expected that the thread should have executed completely and that the output data file should have contained 5 lines. This is not happening
I need an explanation for this behavior.
AS per the ink What happens to a detached thread when main() exits?, does it mean that the detached thread would automatically terminate when the main exits ?

I need an explanation for this behavior.
When main returns, the process is terminated. If there was a thread running, there are no guarantees that it will have a chance to finish.
Furthermore, technically touching any global state after main has returned results in undefined behaviour because all static storage objects will be destroyed by the main thread.
Basically, std::thread::detach is rarely useful because you simply have to use some other way to join the thread instead. There's no standard way to "wait for all detached threads and then stop". There are platform specific ways though (pthread_exit).

Related

cleanup (with delete) in a thread fails [duplicate]

This question already has answers here:
Starting thread causing abort()
(2 answers)
std::thread causes program to abort
(1 answer)
Closed 1 year ago.
Why using delete in a thread fails, but not if called synchronously ?
class dummyclass{};
main()
{
vector<dummyclass*> testlist{};
for(int i=0; i<5; i++)
{
auto value = new dummyclass();
testlist.push_back(value);
}
thread cleanuptest([&]() {for (auto x : testlist) delete x;}); // fails (abort())
}
EDIT/COMMENT
detach and join are the right solutions.
In the case main() is actually a method in a bigger program, which continues to live, detach() is interesting.
In the case of unit tests, then calling join() in the destructor of the class to test is cleaner.
The problem with your program is that your main() function exits before the cleanuptest() thread has a chance to run to completion, taking the testlist object with it. So when cleanuptest() runs, it will likely be trying to access a vector that has already been destroyed (or is in the process of being destroyed, depending on the timing of when the threads execute; they are running asynchronously with respect to each other so their relative timing is indeterminate).
The other problem (which is likely the source of the abort() call) is that the std::thread destructor is detecting that you are destroying the thread object without having called either join() or detach() on it first, which is considered a programming error.
The fix is easy, just add this line to the bottom of main():
cleanuptest.join();
The join() method won't return until the child thread has exited, so it will guarantee that testlist remains valid until the child thread is done using it.
Your main is finishing before the thread has a chance to finish which is causing the abort. You should cleanuptest.join() the thread to let it finish before main exits.

Std thread detach

Having this simple example:
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
void new_thread(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "New thread - exiting!\n";
}
int main() {
std::thread (new_thread, 5).detach();
std::cout << "Main thread - exiting!\n";
return 0;
}
Is it possible for the new_thread not to be automatically terminated by the main thread and to do it's work - outputs New thread - exiting! after 5 secs?
I'm NOT mean the case of join when the main thread waits for a child, but for the main thread to detach the spawned thread and terminates leaving the new thread doing it's work?
Calling detach on a thread means that you don't care about what the thread does any more. If that thread doesn't finish executing before the program ends (when main returns), then you won't see its effects.
However, if the calling thread is around long enough for the detached thread to complete, then you will see the output. Demo.
[basic.start.main]/5 A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0.
[support.start.term]/9
[[noreturn]] void exit(int status);
Effects:
...
Finally, control is returned to the host environment.
You seem to expect that when main returns, the program waits for all threads to finish - in effect, implicitly joins all detached threads. That's not what happens - instead, the program terminates, and the operating system cleans up resources allocated to the process (including any threads).
detach separates your thread from the main thread. You want to use join()
Separates the thread of execution from the thread object, allowing
execution to continue independently. Any allocated resources will be
freed once the thread exits.
After calling detach *this no longer owns any thread.
From ref

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.

Why does my thread not run in background?

In the listing bellow, I expect that as I call t.detach() right after the line when the thread is created, the thread t will run in background while the printf("quit the main function now \n") will called and thenmain will exit.
#include <thread>
#include <iostream>
void hello3(int* i)
{
for (int j = 0; j < 100; j++)
{
*i = *i + 1;
printf("From new thread %d \n", *i);
fflush(stdout);
}
char c = getchar();
}
int main()
{
int i;
i = 0;
std::thread t(hello3, &i);
t.detach();
printf("quit the main function now \n");
fflush(stdout);
return 0;
}
However from what it prints out on the screen it is not the case. It prints
From new thread 1
From new thread 2
....
From new thread 99
quit the main function now.
It looks like the main function waits until the thread finishes before it executes the commandprintf("quit the main function now \n"); and exits.
Can you please explain why it is? What I am missing here?
The problem is that your thread is too fast.
It's able to print all 100 strings before main gets a chance to continue.
Try making the thread slower and you'll see the main printf before that of the thread.
It happens, based on your OS scheduling. Moreover the speed of your thread affects the output too. If you stall the thread (change 100 to 500 for example), you will see the message first.
I just executed the code and the "quit the main function now." message appeared first, like this:
quit the main function now
From new thread 1
From new thread 2
From new thread 3
From new thread 4
...
You are right about detach:
Detaches the thread represented by the object from the calling thread, allowing them to execute independently from each other.
but this does not guarantee that the message "quit the main function now" will appear first, although it's very likely.
It looks like the main function waits until the thread finishes before it executes the command printf("quit the main function now \n"); and exits.
That's because when you create a thread, it gets scheduled for execution, but the order of events across threads is no longer sequential, ordered, or deterministic. In some runs of your program, the output of hello3 will occur before quit the main function now, in some runs it'll print afterwards, and in some runs, the output will be interleaved. This is a form of Undefined Behavior normally referred to as a "Race Condition". In most (but not all) cases, the output of hello3 prints last because there's some overhead (varies by the OS and processor) in setting up a thread, so the several microseconds it takes to properly build the thread and ready it for execution takes so long that the printf statement in your main function already had time to execute and flush before the thread was ready to run.
If you want explicit evidence that things are running concurrently, you should add more work into the main thread before the quit statement so that it becomes unlikely that the main function will finish before the thread is ready to start executing.
There are two major problems with your code:
As soon the main function exits, you will have undefined behaviour because the variable i, referenced by the detached thread, no longer exists.
As soon the whole process ends after the main function returns, the detached thread will also die.

How to delete pthreads?

I want use 5 threads on C++ program. I want create new thread when old ends working. How to implement it? How delete old threads?
Thanks!
You can use pthread_join for this purpose:
The pthread_join() function shall suspend execution of the calling
thread until the target thread terminates, unless the target thread
has already terminated. On return from a successful pthread_join()
call with a non-NULL value_ptr argument, the value passed to
pthread_exit() by the terminating thread shall be made available in
the location referenced by value_ptr. When a pthread_join() returns
successfully, the target thread has been terminated. The results of
multiple simultaneous calls to pthread_join() specifying the same
target thread are undefined. If the thread calling pthread_join() is
canceled, then the target thread shall not be detached.
You can do something of this sort,
In main, create 5 threads (detached ones possibly).
When a thread is about to terminate create a new detached thread
(and use a variable protected by a lock which indicates number of threads running
currently, if its less than 5 create thread else exit) within the
thread before exiting.
That way you will continuously create new threads.
Detached threads run detached from other threads(main included), no one waits for them to complete their execution (They don't make a thread to stop executing). Whereas, when you use pthread_join(threadName,NULL) the thread calling this function has to wait until threadName has terminated. [Both, pthread_detach and pthread_join ensure the threads resources are released]
There is nothing like deleting pthreads.
Something this way,
static int count = 5;
pthread_mutex_t mutexForCount = PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* tFn(void* arg)
{
std::cout<<"\nI am "<<pthread_self();
pthread_mutex_lock(&mutexForCount);
count--;
if(count<=5)
{
pthread_t temp;
pthread_create(&temp,&attr,tFn,NULL);
count++;
}
pthread_mutex_unlock(&mutexForCount);
}
int main()
{
pthread_t threadArray[5];
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(int i = 0;i<5;i++)
{
pthread_create(&threadArray[i],NULL,tFn,NULL);
}
for(int i = 0;i<5;i++)
{
pthread_join(threadArray[i],NULL);
}
pthread_exit(NULL);
}
Note: The attribute and the mutex variables should be destroyed at the end of the program. I have assumed this program runs continuosly.
The thread ends when the thread function exits.