C++ std::thread should be created on heap or on stack - c++

Lets say i have a thread that is being created and detached on the stack like this:
void foo()
{
while(true){};
}
void runThread()
{
std::thread t(foo);
t.detach();
}
int main()
{
runThread();
}
The program means nothing of course, But what happens after we detach and exit runThred ? it was allocated on the stack so basically t will be destroyed after we exit runThred, but the thread itself will go on running regardless to the main thread because it is detached.
Is the best practice in such an example is to create it on the heap and save a pointer to it doing whatever (dcor) after that?
Or it means nothing if the t variable is destructed and we should just "ignore" it?

The std::thread object represents a handle to the thread through which it can be operated on. But once you call detach there is no connection between the object and the actual thread of execution.

Related

lifetime of pthread_t in constructor of class

I'm reading the source code of a project, which is developed with C++98 on Linux.
There is such a piece of code:
class Test {
public:
Test();
static void func(void *arg) {
pthread_detach(pthread_self());
Test *obj = (Test*)arg;
// do something
}
};
Test::Test() {
pthread_t tid; // ???
pthread_create(&tid, NULL, Test::func, this);
}
This is quite clear: a thread is created in the constructor of Test, which calls the function func, and this thread would be detached.
But I'm worrying about pthread_t tid;. When the construcor returns, the variable tid, as a local variable, should be released. Am I right? However, we have passed its address as the first parameter of pthread_create.
Will it cause some lifetime issue, such as a segment fault?
When you call pthread_create, it saves the ID of the thread in tid.
It doesn't save the address of tid. It just puts the ID there before it returns.
So there is no problem.
However, if this bothers you, you should call pthread_detach(tid) in Test::Test instead of pthread_detach(pthread_self()) inside the thread.
It is allowed for a thread to detach itself, but it is slightly strange, because the purpose of pthread_detach is to tell the system that nobody is going to wait for this thread (by calling pthread_join), so the thread can be destroyed as soon as it finishes. Usually, whoever is creating the thread decides whether to wait for it or not - not the thread itself.

is it safe to detach a thread and then let it go out of scope (and have it still running)?

I have the following code, which I think works ok (forgive the silly/contrived example).
void run_thread()
{
std::thread t([]{
while(true)
{
// keep getting chars... to stop peoples eye's hurting : )
char c = getchar();
}
});
t.detach(); // Detach thread
// thread goes out of scope here - but is it ok because its detached??
}
int main()
{
run_thread();
// Wait here forever
while (true) {;}
}
But after re-reading it I have a doubt about it. Thread t goes out of scope. I can't remember now if it is safe to do this after you have called detach()... I think it is, but as I say I have a nagging doubt. Can anyone confirm if this is good/bad practise?
Thread t goes out of scope. I can't remember now if it is safe to do
this after you have called detach()
You detach() because you want to disassociate the actual running thread with the thread object. So after } t goes out of scope but the actual thread will keep on running until its instruction completes.
If it weren't for detach() std::terminate would have killed the thread at }
detach basically releases the std::thread object instance which is the C++ "handle" to the actual OS thread, thereby making it impossible to join the thread later.
In most cases it's better to keep the thread instance around at some global scope so that you can join it later, for example before exiting main. That way you can ensure all threads finish before the main thread.
For example:
std::thread t; // can be "empty"
void run_thread()
{
t = std::thread([]{
while(true)
{
// keep getting chars...
char c = getchar();
}
});
}
int main()
{
run_thread();
// Wait here
std::this_thread::sleep_for(30s);
// Before exiting wait for the thread to finish
if (t.joinable())
t.join();
}
Such a usage is the point of detach.
Yes, it is ok and safe in you code. But it does not have any sense. main function will utilize CPU and a thread function will get less CPU time. You can attach to forever thread and reach similar behaviour: run_thread will never exit, thus main will never exit.
void run_thread()
{
std::thread t([]{
while(true){/* also run forever */;}
});
// Wait here forever
t.attach();
}
int main()
{
run_thread();
}

Giving a std::shared_ptr<std::thread> to itself. Defined or Undefined behavior

I have te following code:
void launchThread() {
std::shared_ptr<std::thread> t;
t = std::make_shared<std::thread>([t] {std::cout<< "HelloWorld"<<std::endl;});
t->detach();
}
int main(){
launchThread();
somthing that takes a while....
}
If I'm correct the thead should keep itself alive using the shared pointer till the thread itself runs out of scope. But I wonder what happens when the shared pointer gets destructed, will the thread be cleaned properly? Or is this bad practice?
std::thread::detach releases ownership - when the shared_ptr is destroyed nothing will happen to the detached thread of execution.
This is bad practice because you could simply write...
std::thread{[]{ std::cout<< "HelloWorld" << std::endl; }}.detach();
...to spawn a background thread that cleans up after itself.

thread access shared variables after main thread exit

What would happen in a multi-thread C++ program if a detached thread accesses shared variables(e.g. global variable) after the call thread exits and destruct the shared variable?
class A {
public:
A() { printf("Constructing A\n"); }
~A() { printf("Destructing A\n"); }
void printSomething() { printf("A is printing\n"); }
}
A a;
void thread_func() {
printf("begin thread.\n");
sleep(3); // make sure main thread exit first
a.printSomething();
printf("ending thread");
}
int main(int argc, char** argv) {
std::thread t(thread_func);
t.detach();
return 0;
}
The program produces:
bash$ ./a.out
Constructing A
Destructing A
bash$
It seems main thread created global variable a and destroy it when exiting. Then what would happen after 3 seconds if the detached child thread tries to access this global variable?
And another confusion is, why does main thread clear up all resources when it exits? Looks like the lifetime of global variable is only dependent on main thread?
Processes exit when main() returns, or any thread calls exit() or _exit().
However, main() can call pthread_exit() - and that will not terminate the process. Per the Linux pthread_exit() man page:
When a thread terminates, process-shared resources (e.g., mutexes,
condition variables, semaphores, and file descriptors) are not
released, and functions registered using atexit(3) are not called.
After the last thread in a process terminates, the process terminates
as by calling exit(3) with an exit status of zero; thus,
process-shared resources are released and functions registered using
atexit(3) are called.
Threads do not have their own memory per-se, but share memory with their parent process. They are tied to their parent; therefore, whenever the parent dies, it's child threads are also killed off.

std::thread::detach causes crash after original caller is destroyed

struct Test {
bool active{true};
void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}
Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}
~Test() {
// somehow stop the detached thread?
}
};
When an instance of Test is initialized, it spawns and detaches an std::thread which runs in background. When the same instance is destroyed, the previously mentioned thread tries to access the active member, which was destroyed along with the instance, causing a crash (and an AddressSanitizer backtrace).
Is there a way to stop the detached thread on ~Test()?
The design is bad. How should a thread running in background until the caller is destroyed be spawned/handled correctly?
Make the thread a member of the class, and instead of detaching it in the constructor, join it in the destructor. To stop the thread from looping, you can have a boolean inside the class that signals whether the thread should continue running or not (std::atomic<bool> update).
The thread could be executing this: [this] { while (update) threadUpdate(); }.
In the destructor of your class, do update = false, and call thread.join()
You can't stop detached threads. That's the point of .detach() - you don't have any way to refer to the detached thread anymore, at least as far as the C++ standard specifies. If you want to keep a handle to the thread, store the std::thread and call .join() in the destructor.