Why can a local variable be accessed in another thread created in the same class?

后端 未结 5 566
误落风尘
误落风尘 2021-01-31 11:38

I couldn\'t really find anything on this exact topic, so please lead me toward the right direction, if a question already exists.

From what I have learned about .NET, it

5条回答
  •  半阙折子戏
    2021-01-31 12:29

    Memory locations are not isolated to a single thread. It would be really inconvenient if they were. Memory in the CLR is only isolated at the application domain boundary. That is why there is a separate instance of each static variable per AppDomain. However, threads are not tied to any one particular application domain. They can execute code in more than one application domain or none (unmanaged code). What they cannot do is execute code from more than one application domain at the same time. What this means is that a thread cannot simultaneously have access to data structures from two different application domains. That is why you have to use marshaling techniques (via MarshalByRefObject for example) or use communication protocols like .NET Remoting or WCF to gain access to data structures from another application domain.

    Consider the following unicode art diagram of a process hosting the CLR.

    ┌Process───────────────────────────────┐
    │                                      │
    │ ┌AppDomain───┐        ┌AppDomain───┐ │
    │ │            │        │            │ │ 
    │ │       ┌──────Thread──────┐       │ │
    │ │       │                  │       │ │
    │ │       └──────────────────┘       │ │
    │ │            │        │            │ │
    │ └────────────┘        └────────────┘ │
    └──────────────────────────────────────┘
    

    You can see that each process can have more than one application domain and that a thread can execute code from more than just one of them. I have also tried illustrate the fact that a thread can execute unmanaged code as well by showing its existence outside of the left and right AppDomain blocks as well.

    So basically a thread has trivial and non-trivial access to any data structures in the same application domain that it is currently executing in. I am using the term "trivial" here to include memory accesses (data structures, variables, etc.) via public, protected, or internal members from one class to another. A thread in no way prevents this from occurring. However, using reflection you could still gain access to even the private members of another class. That is what I am calling non-trivial access. Yes, it involves a bit more work on your part, but there is otherwise nothing fancy going on once you have completed the reflection calls (which by the way must be allowed by code access security, but that is a different topic). The point is that a thread has access to pretty much all of the memory in the same application domain it is executing in.

    The reason why a thread has access to almost everything in the same application domain is because it would be insanely restrictive if it did not. Developers would have to put forth a lot of extra effort to share data structures between classes when working in a multithreaded environment.

    So to sum up the salient points:

    • There is not a one-to-one relationship between a data structure (class/struct) or its constituent members and a thread.
    • There is not a one-to-one relationship between a thread and an application domain.
    • And technically there is not even a one-to-one relationship between an OS thread and a CLR thread (though in reality I know of no mainstream implementations of the CLI that deviate from that approach1).
    • Obviously a CLR thread is still confined to the process in which it was created.

    1Even the Singularity operating system appears to directly map .NET threads to the operating system and hardware.

提交回复
热议问题