views:

32

answers:

2

I read that threads share the memory address space of it's parent thread. If that is true , why can't a thread function access a local variable belonging to it's parent thread ?

void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );

}

If the thread shares the address space , then the function PrintVar should have been able to print the value of variable a , right ?

I read this piece of info on http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

Threads in the same process share: Process instructions Most data open files (descriptors) signals and signal handlers current working directory User and group id

If that is true, then why does int a not qualify as a shared variable ?

I'd like to see an example code where the file descriptors are shared

+2  A: 

you couldn't do that even if this were not a thread, because a is out of scope.

put a in the global scope, like so:

int a;
void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );

}

This is actually not an issue of threads. consider the following code:

void PrintVar(){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   PrintVar();
}

This obviously won't work, because the variable name a declared in main is not visible in PrintVar, because it's in the local scope of another block. This is a compile-time problem, the compiler just doesn't know what you mean by a when you mention it in PrintVar.

But there is also another threading issue. when the main thread of a process exit, all other threads are terminated (specifically, when any thread calls _exit, then all threads are terminated, and _start calls _exit after main returns). but your main returns immediately after invoking the other thread. To prevent this, you should call pthread_join which will wait for a thread to exit before returning. that'll look like this

int a;
void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   void *dummy;
   a = 10;

   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );
   pthread_join( thr, &dummy);
}
TokenMacGuy
Global variables get shared by default. So , by shared address space , you mean _only_ global variables get shared ?
Sharat Chandra
@Sharat: no, local variables are "shared" just as much as anything else. The problem arises if you pass the address of a local variable to another thread, but then exit from the function (so the variable is no longer valid) but the other thread doesn't know it can't use that variable any more.
Jerry Coffin
@jerry : so u mean to say that once a child thread exits , the local variable in the parent thread - which was passed as an argument to child thread, ceases to exist ?
Sharat Chandra
@Sharat: No, I mean when the function in the parent thread exits, the local variable ceases to exist, so if you've passed it to the child thread, it's easy for the child thread to (unknowingly) continue to use it after it no longer exists.
Jerry Coffin
Thanks Jerry. Got that :-)
Sharat Chandra
So summing up my understanding : "shared address space" means that local variables can be shared by child threads *only* by explicitly passing it as an argument to the to the child thread.Correct ?
Sharat Chandra
@Jerry and TokenMacGuy : The "shared address space" is actually achieved by "passing" the address as reference to the thread , and not by any other means. Right ?
Sharat Chandra
@Sharat: the shared address space means they all share the same set of addresses, so an address in one thread is meaningful in another, and refers to the same variable. Contrast to separate processes, where an address in one process may not mean anything in another, or might refer to something entirely different, so even if you try to pass an address from one process to another, you won't (normally) be able to use it in the other process.
Jerry Coffin
@Jerry : So suppose an address is passed from one process A to another process B, this address would be non-existent in the virtual memory space of process B. Hope my understanding is correct
Sharat Chandra
@Sharat: it's not guaranteed to be nonexistent -- it might happen to refer to something in process B, but generally not the same thing as in process A. The fact that it refers to anything is mostly a matter of there being only so many addresses available, so there's at least some chance it'll be valid in both. In a 32-bit system it usually will be. In a 64-bit system (lots more available addresses) there's a much better chance it won't be.
Jerry Coffin
@jerry : Yup . Thank you so much for your time !
Sharat Chandra
+1  A: 

The child thread can access the variable in the stack of the parent thread, it just needs to know the variable's address. For example, you could do it like this:

void* PrintVar(void* arg){
   int * a = (int *) arg;
   printf( "%d\n", *a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, &a );
}

Note that this sort of thing can be tricky, since you have to (one way or another) guarantee that (a) won't get destroyed while the child thread is still accessing it. (In this case you'd probably want to call pthread_join() at the end of main(), so that the main thread will block there and not return from main() until after the child thread has exited)

Jeremy Friesner
SO this is an example that illustrates how threads share the address space of it's parent. Am I right ?
Sharat Chandra
@Jeremy: So summing up my understanding : "shared address space" means that local variables can be shared by child threads only by explicitly passing it as an argument to the to the child thread. Correct ?
Sharat Chandra
@Jeremy : The "shared address space" is actually achieved by "passing" the address as reference to the thread , and not by any other means. Right ?
Sharat Chandra
Threads in the same process always share the entire address space with each other. But just sharing the same address space isn't sufficient here -- if you want to read/write a variable in another thread's stack (which you apparently do), you also need to know the address of that variable in order to know where to write to.
Jeremy Friesner
Note that "shared address space" only means that from either thread, a given pointer value will reference the same physical bytes of RAM. Contrast that with the case of two different processes, where each process may hold a pointer with the same value, but the two pointers nevertheless point to two different physical memory locations due to virtual memory magic.
Jeremy Friesner