detach() has no output at all
I extended the example in the page 18 as follows. It compiles and runs fine and I can see constructor being called looking at terminal output. But when detach() called, I cant see, any output from the operator() (). I thought operator() will be invoked when my_func is passed my_thread() initialization: std:thread my_thread(my_func) and detach() allows to run in the background even after main() quits. But I dont see any output with detach() is called before exising main(). However, if I replace detach() with join(), it works and I get the loop executing as main() blocks until operator()() finish executing. Can you explain what I did wrong here?
/* This is similar to p13.cpp except it is using example of callable object, in this case
class with () operator defined */
#include <iostream>
#include <thread>
void hello() {
std::cout << "Hello concurrent world.\n";
}
#define DEBUG 1
struct func {
int & i;
func(int & i_) : i(i_){
if (DEBUG == 1) {
std::cout << "func::func() (constructor) entered..." << std::endl;
}
};
void operator() () {
if (DEBUG == 1) {
std::cout << "func::operator() entered..." << std::endl;
}
/*
for (unsigned j=0; j < 1000000 ; ++j) {
if (j % 100000 == 0) {
std::cout << "loop idx j: " << j << ", i: " << i << std::endl;
}
}*/
}
};
void oops() {
int some_local_state = 0;
func my_func(some_local_state);
std::thread my_thread(my_func);
/*Detach() does nothing ?? not sure what happened.. join will print out j-loop.*/
my_thread.detach();
//my_thread.join();
}
int main() {
oops();
}
Ifound similar example on the internet and by the same manner, if I delay the exiting of main() (using chrono API to wait one sec (whcih is a very long time!), followed by detach() now I do see outputs now. So lack of output I mentioned above is main() exits without waiting.
On 2024-10-17 08:32, ggankhuy wrote:
I extended the example in the page 18 as follows. It compiles and runs fine and I can see constructor being called looking at terminal output. But when detach() called, I cant see, any output from the operator() (). I thought operator() will be invoked when my_func is passed my_thread() initialization: std:thread my_thread(my_func) and detach() allows to run in the background even after main() quits. But I dont see any output with detach() is called before exising main(). However, if I replace detach() with join(), it works and I get the loop executing as main() blocks until operator()() finish executing. Can you explain what I did wrong here?
After calling detach you exit the program. Since the code does not wait for the thread to finish, then it is not guaranteed to have run any particular part of the code on that thread. e.g. the OS might not have scheduled your thread to even start yet.
This is why, if you add a delay after detach then you see output: now your code has run --- it's still not guaranteed, but if there is nothing else for your system to do then it will run your code. Similarly, if you explicitly wait for it with join then it is guaranteed to run.
Cheers, Anthony
Yeah for join(), it is pretty much clear, for detach() hmm, in the book, it says even after main() exits, if detached, thread should be owned by C++ runtime and if I understand correctly, it says "detached threads truly run in the background, ownership and control are passsed over to the C++ Runtime Lib", I do see there is some ambiguity in that it does not tell whether it should continue to run after main() exists, but if it becomes completely detached would not that mean it should continue to run after main() exit? Or does it simply stating, while main() is running, it will be independent and run as daemon?
I might have found official explanation for this, but in different C book: "Programming with POSIX threads" David R. Butenhof p37. "The initial tthread (main) is special because Pthreads retains traditional UNIX process behavior when the function main returns; that is the process terminatese without allowing other threads to complete..." Related paragraph although it is not exactly relevant,but nevertheless looks interesting to know: "Detaching a thread that is still running does not affect in any way, it just informs the system thread's resources can be reclaimed when it eventually terminates.
it seems join will be just remedy for main not waiting for other to finish if detach is called. Interesting note from same book, it also says pthread_exit() can be used to allow the process to continue untill all threads are terminated. But c++ thread does not seem to offer such API https://en.cppreference.com/w/cpp/thread/thread perhaps jsut use join then.