进程、应用程序域、程序集、对象上下文(转载)

 看到了这么一篇文章,觉得讲的还可以,所以就直接转载过来,原文: http://www.360doc.com/content/10/0608/00/495229_31864349.shtml

简单的说,进程可以承载一组相关的.NET程序集,而应用程序域(简称AppDomain是对该进程的逻辑细分。一个应用程序域进一步被细分成多个上下文边界,这些边界用来分组目的相似的.NET对象。使用上下文的概念,CLR便能够确保恰当地控制那些带特殊运行时要求的对象。

传统的进程

用来描述一组资源和程序运行所必需的内存分配。对于每个被加载到内存的可执行程序,在她的生命周期中操作系统会为之单独且隔离的进程。由于一个进程的失败不会影响其他的进程,使用这种方式,运行库环境将更加稳定

通过任务管理器,我们可以查看机器上正在运行进程的统计信息:进程的标示符(PID)以及映像名称。

 
  进程从来不执行任何东西,它只是线程的容器。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,此线程负责执行包含在进程的地址空间中的代码。
 

线程概述

线程是进程中的基本执行单元(a path of execution)。进程的入口点创建的第一个线程为主线程。仅仅包含一个主线程的进程是线程安全的。但是,单线程的应用程序用户响应不好。

开发者使用多线程,有助于改善程序的总体响应。Win32 API可以让主线程使用如CreateThread()之类的函数,另外产生次线程。每个线程都是进程中的一个独立执行单元(unique of execution)。比如:一个应用程序可以产生一个工作线程来执行强度大的工作(比如传输大文件),当这个次线程正在忙碌的时候,主线程仍然可以对用户的输入保持响应。

 

当然,如果单个进程中的线程过多的话,性能反而会下降,因为CPU需要花不少时间在这些活动线程的来回切换上。另外,单CPU的计算机并没有能力同一时间运行多个线程。当一个县城的时间片用完的时候,他会被挂起(suspended),以便执行其他的线程。(找详细点的资料)

 如果觉得太复杂,那么只需要记住:线程是Win32进程的独立执行的单元,每一个进程都有一个主线程,并且每个进程还可以以编程的方式创建额外的线程更多内容可以参考:关于进程和线程『整理』 复习功课:对进程、线程、应用程序域的理解 

 

.NET平台下与进程进行交互

   .NET的基类库可以方便的和进程进行交互。他们位于System.Diagnostics命名空间中,该空间定义了许多的类型,允许我们与系统进程、事件日志和性能计数器进行交互。

 

 
   我们可以看到,与进程打交道的类型有:ProcessProcessModuleProcessModuleCollectionProcessStartInfoProcessThreadProcessThreadCollection
 
 
 

详细的关于Process使用方法可以查阅MSDN,比如获取/设置进程优先级,获取进程打开的句柄数

 

.NET应用程序域

.NET平台下,程序集并没有直接加载进进程中(传统的Win32程序是直接承载的)。.NET可执行程序承载在进程的一个逻辑分区中,术语称应用程序域(简称AppDomain。一个进程可以拥有多个应用程序域,应用程序域的全部目的就是提供隔离性,相比较与传统的:

1.应用程序域是.NET平台操作系统独立性的关键特性。这种逻辑分区将不同操作系统表现加载可执行程序的差异抽象化了。

2.和一个完整的进程相比,应用程序域的CPU和内存占用要小的多。

3.应用程序域为承载的应用程序提供了深度的隔离。一个失败,其他不会失败。

单个进程可以承载多个应用程序域,每个程序域都和该进程的其他程序域隔离开来,无法相互访问。在线程启动的时候,CLR将自动创建这个特定的应用程序域(默认应用程序域)。然后根据需要创建其他程序域。

 
 
 
 

两边都有mscorlib.dll,因为所有关键程序集会被CLR自动加载到每一个应用程序域中。

更多内容:C#强化系列文章六:应用程序域(AppDomain)浅析 寄宿(host)和应用程序域(appdomain) 

 

对象上下文

 

应用程序域是承载.NET程序集的进程的逻辑分区。与此相似,应用程序域也可以进一步被划分为多个上下文边界(context boundary)。事实上,.NET上下文为单独的应用程序域提供了一种方式,该方式能为一个给定对象建立“特定的家”(specific home)。

 

使用上下文,CLR可以确保在运行时有特殊需求的对象,可以通过拦截进出上下文的方法调用,得到适当的和一致的处理。这个拦截层允许CLR调整当前的方法调用,以便满足给定上下文的设定要求。比如,如果定义一个C#类型需要自动线程安全(使用【Synchronization】特性),CLR将会在分配期间创建“上下文同步”。

 

和一个进程定义了默认的应用程序域一样,每一个应用程序域都有一个默认的上下文(context 0)。大多数.NET对象都会被加载到上下文0中。如果CLR判断一个新创建的对象有特殊需求,一个新的上下文边界将会在承载它的应用程序域中被创建。

 

可以通过Thread.CurrentContext获得上下文,通过contextContextProperties属性获得描述。

 

Code
 
 
 
 总结

1.一个.NET进程可以承载多个应用程序域。每一个应用程序域可以承载多个相关的.NET程序集,并且可以由CLR(或者AppDomain)独立地加载或卸载应用程序域。

2.一个给定的应用程序域中包含一个或多个上下文。使用上下文,CLR能够将“由特殊需求的”对象放置到一个逻辑容器中,确保该对象的运行时需求能够被满足。

 

程序集

一个.NET应用程序可以由多个程序集拼装而成的。程序集,简单来说,就是一个以公共语言运行库(CLR)为宿主的、版本化的、自描述的二进制文件。尽管显示中.NET程序集和以往Win32二进制文件(包括遗留的COM服务对象)的文件扩展名(*.exe*.dll)完全相同,但是两者的内部构成几乎完全不同

程序集可以促进代码重用、确定类型边界、可版本化的单元、自描述的、可配置的。

 

.NET程序集的格式

 

Win32文件首部

Win32文件首部使程序集可以被Windows系列操作系统加载和操作。使用dumpbin.exe结合/headers标记打开一个.NET程序集,可以浏览该程序集的Win32文件首部信息。

 

 

 

 

CLR文件首部

为了驻留于CLR中,所有的.NET文件都必须还有CLR首部数据块。它定义了多个标记,它们使得运行库可以了解到托管文件的布局。例如,文件中元数据和资源的位置、程序集构建的运行库版本、公钥值等。使用dumpbin.exe结合/clrheader

 

 

 

CIL代码

程序集的核心部分包含CIL代码,这些CIL代码是独立于平台和CPU的中间语言。运行时,程序集内部的CIL代码才被编译成特定平台和CPU的指令。

类型元数据

元数据完整的描述了程序集内含另行和引用外部类型的格式。

程序集清单

详细记录了程序集中的每一个模块,构建程序集的版本以及该程序集引用的所有外部程序集。

可选的嵌入资源

 

 

单文件程序集和多文件程序集

程序集由多个模块组成。大多数情况下,程序集只由一个模块组成。这种情况下,(逻辑)程序集和实际的(物理)二进制文件是一一对应的(因此被称为单文件程序集)。多文件程序集市一个.NET*.dll的集合,这些DLL作为单个逻辑单元进行部署和版本化。通常,其中一个会作为主模块,它将包含程序集级别的清单。主模块的清单记录了它依赖的每一个*.dll文件 

 

 

私有程序集

私有程序集要求放置在客户端应用程序所有在目录(应用程序目录)或者子目录下。

探测过程

.NET运行环境使用一种叫探测(probing)的技术解析私有程序集的位置(这项技术并没有这个名字听起来那样具有侵略性)。

 

共享程序集

一个共享程序集不在部署使用它的应用程序目录中,它安装在GACGACWindows下名为Assembly的目录。

强名称

在部署程序集到GAC之前,必须赋予它一个强名称,用于标示给定.NET二进制文件的发行者。它的作用就好比全局唯一标示符(GUID)在COM中的作用。它由一组相关数据组成:

程序集的有好名称(程序集名减去文件扩展名)

程序集的版本号(使用[AssemblyVersion]特性赋值)

公钥值(使用[AssemblyKeyFile]特性赋值)

用于本地化得可选的区域性标识(使用[AssemblyCulture]特性赋值)

嵌入的数字签名,使用基于程序集内容的散列值和私钥值生成。

 

原文地址:https://www.cnblogs.com/Langzi127/p/1791268.html