pthread_exit() and pthread_join()

Hi,
does anyone have an idea why this code
Code:
#include <stdio.h>
#include <pthread.h>

void *do_some_work(void *arg)
{
        int i, j;
        for(i = 1; i < 100; i++)
        {
                for(j = 1; j < 100; j++)
                {
                        i / j;
                }
        }
        printf("1\n");
        int k = 5;
        pthread_exit((void *) &k);
}

int main()
{
        pthread_t joinable_thread;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
        int status = pthread_create(&joinable_thread, &attr, do_some_work, NULL);
        if(status)
        {
                printf("pthread_create() error\n");
                return -1;
        }
        int *l;
        status = pthread_join(joinable_thread, (void *) &l);
        if(status)
        {
                printf("pthread_join() error\n");
                return -1;
        }
        printf("2\n");
        printf("%d\n", *l);
        pthread_exit(NULL);
}
prints
Code:
1
2
5
on FreeBSD and Solaris
and
Code:
1
2
0
on linux
so it works as expected (at least as I would expect) on FreeBSD and Solaris but not on linux
is it possible that the "k" variable is destroyed before pthread_join() finishes?
Yes, I realize I'm asking about linux in the FreeBSD forum :)
I'm just trying to understand what is the problem? Is it incorrect to try to pass a reference to a stack variable from one thread to another using pthread_exit/pthread_join ?

10x
 
Should not pass reference to stack variable

Probably you shouldn't ask here, but yes, it is incorrect to try to pass a reference to a stack variable from one function to other function (even on the same thread). If k is global or is allocated using malloc, the last line should print "5".

Try valgrind to check for this kind of error (it's in the ports).
 
Hi,
I agree that passing refereces to stack variables from callee to caller is incorrect however I think this is not strictly true when using pthread_exit() and pthread_join()

...from opengroup docs:
The pthread_join() or pthread_detach() function should eventually be called for every thread that is created with the detachstate attribute set to PTHREAD_CREATE_JOINABLE so that storage associated with the thread may be reclaimed.
if I understand correctly even though the stack of the terminated thread is subject of clean up it can be reclaimed i.e. I could acutally use the stack variables

...or I don't understand the meaning of this: "storage associated with the thread may be reclaimed"

of course if I look at the docs for pthread_exit():
After a thread has terminated, the result of access to local (auto) variables of the thread is undefined. Thus, references to local variables of the exiting thread should not be used for the pthread_exit() value_ptr parameter value.
and we are back to the same question: can I pass a reference to stack variable to pthread_exit() if pthread_join() is called on the other "side"?

10x
 
You creating variable in the stack with
Code:
int k = 5;
in your func
Then exit, giving pointer to it
Code:
 pthread_exit((void *) &k);
So stack variable is not guarantied to save when you exit func..

Try make it static and test changes
 
mgp said:
Hi,
I agree that passing refereces to stack variables from callee to caller is incorrect however I think this is not strictly true when using pthread_exit() and pthread_join()

...from opengroup docs:

if I understand correctly even though the stack of the terminated thread is subject of clean up it can be reclaimed i.e. I could acutally use the stack variables

You can specify your own stack storage for a thread using pthread_attr_setstack, and you can reclaim (clean up) this storage after pthread_join returns. You still can't refer to any auto (stack) variables.
 
mgp said:
and we are back to the same question: can I pass a reference to stack variable to pthread_exit() if pthread_join() is called on the other "side"?

10x

I am pretty sure that this has nothing to do with POSIX threads. You should never return pointers to function's internal stack because they can be accounted for as invalid after function returns. By trying to read such pointers you can even trigger a segfault.
 
thanks for your answers
I just thought that pthread_exit() and pthread_join() might do some magic with the stack but since you all (the pthread_exit() man page also) say they don't I guess they don't :)

cheers
 
mgp said:
Hi,
does anyone have an idea why this code
Code:
#include <stdio.h>
#include <pthread.h>

void *do_some_work(void *arg)
{
        int i, j;
        for(i = 1; i < 100; i++)
        {
                for(j = 1; j < 100; j++)
                {
                        i / j;
                }
        }
        printf("1\n");
        int k = 5;
        pthread_exit((void *) &k);
}

int main()
{
        pthread_t joinable_thread;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
        int status = pthread_create(&joinable_thread, &attr, do_some_work, NULL);
        if(status)
        {
                printf("pthread_create() error\n");
                return -1;
        }
        int *l;
        status = pthread_join(joinable_thread, (void *) &l);
        if(status)
        {
                printf("pthread_join() error\n");
                return -1;
        }
        printf("2\n");
        printf("%d\n", *l);
        pthread_exit(NULL);
}
prints
Code:
1
2
5
on FreeBSD and Solaris
and
Code:
1
2
0
on linux
so it works as expected (at least as I would expect) on FreeBSD and Solaris but not on linux
is it possible that the "k" variable is destroyed before pthread_join() finishes?
Yes, I realize I'm asking about linux in the FreeBSD forum :)
I'm just trying to understand what is the problem? Is it incorrect to try to pass a reference to a stack variable from one thread to another using pthread_exit/pthread_join ?

10x

Well... you'd have better luck getting an answer here than in linux forums :e it seems to me that the freebsd understands how linux works much better than linux folks often do.�e
 
Back
Top