Why pthread_exit acts like pthread_join? - c++

Code:
void *PrintHello(void *threadid)
{
cout<<"Hello"<<endl;
sleep(3);
cout<<"Still PrintHello is alive"<<endl;
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
cout<<"Calling thread:"<<t<<endl;
pthread_create(&threads[0], NULL, PrintHello, NULL);
//pthread_join(threads[0],NULL);
cout<<"Main exits"<<endl;
pthread_exit(NULL);
}
Why pthread_exit(NULL) here acts like pthread_join()? i.e Why exiting main not destroying the printHello thread and allowing it to continue?

pthread_exit() terminates only the calling thread. So when you call it from main(), it terminates the main thread while allowing the process to continue. This is as expected.
If you call exit() (or an implicit exit from by returning) instead, it'll terminate the whole process and you will see printHello terminated as well.

There's quite a good resource here but to quote the part which explains your problem:
Discussion on calling pthread_exit() from main():
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done.

Related

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

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.

Corrupted memory with Hello World with Pthreads

I'm working through some simple pthread examples form llnl.computing.gov pthreads tutorial. The program on the website prints out the address of the threadid, but I would like to pass the address of the id to PrintHello, and then use dereference the address to get the id. I think with the sleep in there every thread should print 8 (the number of threads). The code is
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_THREADS 8
void *PrintHello(void *threadid)
{
long *taskid = (long *)threadid;
sleep(1);
printf("Hello from thread %ld\n", *taskid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0;t<NUM_THREADS;t++) {
printf("Creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
When I compile and run this in Cygwin it seg faults with stack corruption errors. If I rewrite PrintHello as:
void *PrintHello(void *threadid)
{
long taskid = (long) threadid;
sleep(1);
printf("Hello from thread %ld\n", taskid);
pthread_exit(NULL);
}
it doesn't seg fault, it just prints the address and I would like to dereference the address and get the value of t from main.
Does anyone have some pointers on how to accomplish that goal? I know I can pass t to pthread_create instead of &t but I want to do it this way for learning purposes.
When you call pthread_exit(NULL) from the main thread, it terminates that thread. At that point, any local variables in the main function, including t, are destroyed and can no longer be used.
If the main thread exits before all of your worker threads are finished using t (via the pointer you pass to them via pthread_create), your program exhibits undefined behavior.
The program contains a race condition because the access of the variable t from the worker threads and the destruction of the variable t from the main thread are unsynchronized. One way to fix this problem would be to have the main thread join with each of the worker threads (via pthread_join) before it exits.
1) you pass the address of t so every thread will get a pointer to the same variable, that's not the thread ID, it's a long which has a value that keeps changing. You are modifying the variable in main and reading it in each other thread, which is a data race.
2) Probably what happens is that by the time the new threads execute the loop in main has finished and the variable has gone out of scope. When main exits its local variables will be popped off the stack, so when the other threads access t it is no longer on the stack. You don't have any synchronisation in your program to prevent that, so you have another data race there. You need to wait in main for the threads to finish, which you can do by calling pthread_join to wait for each one, but that still won't change the fact the other threads are trying to read a variable while it's being written to by another thread.
3) There's no need to call pthread_exit there, returning from the function or from main automatically exits the thread (just like calling exit(0) causes main() to finish)
Some pointers? Well, you have plenty of them in your thread functions...
The problem: you can't safely pass around the address of your local variable - it gets out of scope when main exits. You'll need to either declare the pointer as a static global variable, or malloc() sizeof(long) bytes of memory and use that.

Calling pthread_cancel on a join'ed thread causes segfault under linux

The following code ends with a segmentation fault on the first call to pthread_cancel but only under linux. Under Mac OS it runs fine. Am I not allowed to call pthread_cancel on a thread that has finished running? Maybe I should not call pthread_cancel at all?
#include <iostream>
#include <pthread.h>
using namespace std;
void* run(void *args) {
cerr << "Hallo, Running" << endl;
}
int main() {
int n = 100;
pthread_t* pool = new pthread_t[n];
for(int i=0;i<n;i++) {
pthread_t tmp;
pthread_create(&tmp,NULL,&run,NULL);
pool[i] = (tmp);
}
for(int i=0;i<n;i++) {
pthread_join(pool[i],0);
}
for(int i=0;i<n;i++) {
pthread_cancel(pool[i]);
}
}
See POSIX XSH 2.9.2:
Although implementations may have thread IDs that are unique in a system, applications should only assume that thread IDs are usable and unique within a single process. The effect of calling any of the functions defined in this volume of POSIX.1-2008 and passing as an argument the thread ID of a thread from another process is unspecified. The lifetime of a thread ID ends after the thread terminates if it was created with the detachstate attribute set to PTHREAD_CREATE_DETACHED or if pthread_detach() or pthread_join() has been called for that thread. A conforming implementation is free to reuse a thread ID after its lifetime has ended. If an application attempts to use a thread ID whose lifetime has ended, the behavior is undefined.
If a thread is detached, its thread ID is invalid for use as an argument in a call to pthread_detach() or pthread_join().
You may not use a pthread_t after the thread it refers to has been joined, or if the thread has terminated while detached. Simply remove the pthread_cancel code from your program. It's wrong. pthread_cancel is for cancelling an in-progress thread, and has very tricky requirements for using it safely without causing resource leaks. It's not useful for threads which exit on their own.

pthread - How to start running a new thread without calling join?

I want to start a new thread from the main thread. I can't use join since I don't want to wait for the thread to exit and than resume execution.
Basically what I need is something like pthread_start(...), can't find it though.
Edit:
As all of the answers suggested create_thread should start thread the problem is that in the simple code below it doesn't work. The output of the program below is "main thread". It seems like the sub thread never executed. Any idea where I'm wrong?
compiled and run on Fedora 14 GCC version 4.5.1
void *thread_proc(void* x)
{
printf ("sub thread.\n");
pthread_exit(NULL);
}
int main()
{
pthread_t t1;
int res = pthread_create(&t1, NULL, thread_proc, NULL);
if (res)
{
printf ("error %d\n", res);
}
printf("main thread\n");
return 0;
}
The function to start the thread is pthread_create, not
pthread_join. You only use pthread_join when you are ready to wait,
and resynchronize, and if you detach the thread, there's no need to use
it at all. You can also join from a different thread.
Before exiting (either by calling exit or by returning from main),
you have to ensure that no other thread is running. One way (but not
the only) to do this is by joining with all of the threads you've
created.
the behaviour of your code depends on the scheduler; probably the main program exits before printf in the created thread has been executed. I hope simple sleep(some_seconds) at the end of the main() will cause the thread output to appear :)
the join call waits for the thread to terminate and exit.
if you want your main thread to continue its execution while the child thread is executing, don't call join: the child thread will execute concurrently with the main thread...
Just create the thread with the detached attribute set to on. To achieve this, you can either call pthread_detach after the thread has been created or pthread_attr_setdetachstate prior to its creation.
When a thread is detached, the parent thread does not have to wait for it and cannot fetch its return value.
you need to call pthread_exit in the end of man(), which will cause main to wait other thread to start and exit.
Or you can explicitly call pthread_join to wait the newly created thread
Otherwise, when main returns, the process is killed and all thread it create will be killed.
The thread starts automatically when you create it.
Don't you just need to call pthread_create?
static void *thread_body(void *argument) { /* ... */ }
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, thread_body, NULL);
/* ... */