Ah, address space. There is one and only one address space that belongs to you. All things yours live in that address space.
Now, the address space can be looked at as if it is partitioned into different uses.
Code, the execution path, generally read-only. Some code comes from your executable, some from DLLs, some from shared libraries, etc but it's all just code sitting in your address space.
Constant data (strings, const, things like that), also generally read-only.
Global Memory, a place where your "module wide variables" go, things declared in the scope of the program / cpp file and are visible to all functions. May or may not include the "extern" declaration.
Heap / Pool, read/write memory you can allocate things out of (new/delete and/or malloc/free). Basically, all your dynamic stuff.
Stack (one per thread) where local variables go.
In general, all of this can be seen by all threads in your application and some can change "roles", for example, some of the best known virus entry methods is to convince some poorly written piece of code to execute data as if it were code, but I digress.
You can either access things directly by name or pass pointers or structures / objects around as parameters between functions.
The only thing you have to be careful of is passing the address / pointer to a variable that lives in the stack space of a function / thread to another thread. While the pointer will most likely remain valid, the contents should not be trusted. So don't do that.
Oh, the only other "only thing" is to not pass pointers / addresses of things you eventually "delete" or "free" since again, the pointer is most likely valid but the data cannot be trusted anymore.
Oh, and I'm sure there are other "only things" out there so be careful.
---------------------------
Edit just to remove some potential confusion
---------------------------
Now there are two ways to interpret your question
Quote:
I want to know in which part of the process address space are these synchronization variables stored?
1) The object you create, that is the "HANDLE" that identifies the semaphore / event or object for the critical section, and the answer would be "in your address space" so you can access them, pass them around, etc.
2) The object that represents the thing you can wait on, the queue of waiters, etc. Those are "kernel objects" that live in the kernel's memory space, are "mapped to" by the HANDLE you get back from the create statement, and provide all the stuff the kernel needs to provide you the functionality of "Wait", "Signal", etc. You only indirectly reference these objects through the API defined and with the "HANDLE" given to you.
This separation is true for just about any OS, be it Windows or some unix like offering the POSIX thread synchronization features.