Click here to Skip to main content
15,885,914 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
We know that all the threads in process share the process address space.
We have various synchronization mechanisms like semaphore, mutex, spinlock, critical sections etc . used for thread syncronization.

I want to know in which part of the process address space are these synchronization variables stored?
How one thread gets access to the syncronization variable declared in another thread? Pls correct me if this question is improper.
Posted
Comments
Sergey Alexandrovich Kryukov 8-Nov-11 11:51am    
My 5 for good thinking. Fortunately, OS takes care of this problem, but it did exists for the system programmers who created those implementations of synchronization primitives.
--SA

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.
 
Share this answer
 
v2
Comments
[no name] 8-Nov-11 10:58am    
Great, 5!
Sergey Alexandrovich Kryukov 8-Nov-11 12:02pm    
I voted 4. Basically, all correct, but for such a long text, some important detail are not clear, and the essence of the thread memory (separate stacks) is not explained, so it leave impression that it hardly gives clear understanding of the topic; I understand, it's too hard to do in a short post.
--SA
Chuck O'Toole 8-Nov-11 14:07pm    
did you miss the statement "Stack (one per thread)" in talking about the address space? How much more explanation is needed? I also said " careful of is passing the address / pointer to a variable that lives in the stack space of a function / thread". That should be enough for this level of reply, I'm not writing a document on memory allocation after all.
Sergey Alexandrovich Kryukov 8-Nov-11 14:47pm    
I missed it, sorry.
--SA
This part of phrase found in the question is not correct: "...declared in another thread". A variable of a synchronization primitive is never declared in a thread; only the stacks and the preserved CPU context belong to a thread; all other variables are shared between threads. Access to an object and threads are completely orthogonal categories. The only problem is the parallel access to the object by different threads.

One more clarification: strictly speaking, shared address space is not the address space of a process, but of an Application Domains. Each two Application Domains of the same process are isolated from each other as well as two different processes.

—SA
 
Share this answer
 
v3
Comments
Chuck O'Toole 8-Nov-11 14:14pm    
Well, "declared" is rather ambiguous, does he mean the "actual location of the statement the defines the variable" or the "creating of the object (e.g., CreateEvent()) in another thread"? It turns out that it's really not important where / which thread does the "Create" function, the object created (via its "handle") is visible to the entire process / thread family. What is important is the "scope" of the reference to the variable, could be global, could be passed by value (HANDLE) or could be only scoped to be referenced in one thread. So if you're going to look at this as a 'newbie' type question, you have to allow for the imprecise use of "declared" to mean more than the placement of the variable name.
Chuck O'Toole 8-Nov-11 14:27pm    
Hummm, Application Domains are a relatively new concept for me, I'll have to read up on those to understand how the addressing / process context works out to allow for multiple applications to run within the process family. Something new to figure out.
Sergey Alexandrovich Kryukov 8-Nov-11 14:46pm    
The concept is fairly simple -- address spaces are isolated per Application Domain, by default, only one is created for you, and in this case all your knowledge is totally applicable; almost the same if there are more: Application Domains are composed in the process and are the unit of address space isolation, not the process. Threads, however, can run throw the boundaries between Application Domains, as method addresses are all static and shared. This could be derived logically from all of the above. But if you are using a delegate instance, for example, this is data, and this instance makes no sense beyond the boundary of Application Domain. This is all pretty simple. Main application of Application Domains I know is the ability do unload a plugin. It is not possible to unload any separate assembly (Microsoft could not guarantee process integrity if one could), but one can unload the whole AppDomain with all assemblies loaded inside it. I think it's pretty clear.
--SA
Chuck O'Toole 8-Nov-11 15:32pm    
Well, I understand the notion of separation of "access rights" within the domains, almost a "C2 level" separation with rights. I also get the idea of "marshalling" the arguments that cross the API calls. However, the documentation / description talks about "starting and stopping other Application Domains" almost as if they were separate execution "entities" within the process. Now if all that means is "loading" or "unloading" assemblies, then I get it. It's just the reference to "start / stop" that bothers me. I also read about "separate virtual address space" in the domains. The question is, does the address ranges overlap? That is, are they really separate address spaces or is the one big address space broken up into multiple "protection zones" that only certain domains can access (the rights thing). If it's just protection zones, then I get that too, using "portal instructions" to jump from one level of access to another. Otherwise you are dealing with an entire duplicate memory management system for each domain within a process and that's something I'd have to figure out.
Sergey Alexandrovich Kryukov 8-Nov-11 18:24pm    
I don't really understand what "starting" and "stopping" do you mean. Could you post a reference? Perhaps I could explain it. I must say some Microsoft documentation on this topic fails to explain the essence of things going into rather confusing considerations. In particular, the threading aspect explanation was explained like that. I thinks the memory "protection zone" issue is pretty simple: a domains of access references (note, they are based on virtual memory addresses but not exactly the same as there is an intermediate level of indirection between them, the domain of GC; objects are not just garbage-collected, they can be relocated) is Application Domain, not process. An Application Domain accesses only the references inside the same AppDomain, everything else is IPC.
--SA
For multithreading in VC++/MFC, you need to use AFXBeginThread function. Whose first pararmeter is pointer to global function, prototype is,
UINT FunctionName(LPVOID param);
And second paramater is value to send through param.

You can send any data you want to access through param.
 
Share this answer
 
Comments
rupeshkp728 8-Nov-11 9:19am    
Hey pranit this does not seem to be the answer for my question
Chuck O'Toole 8-Nov-11 9:48am    
Well, technically he did answer this part of your question "How one thread gets access to the syncronization variable declared in another thread?" so don't be too harsh :)
Sergey Alexandrovich Kryukov 8-Nov-11 11:57am    
This expression "...declared in another thread" in invalid. Even though I voted 5 for the question, I tried explain why this is invalid in my solution.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900