zoukankan      html  css  js  c++  java
  • 进程、线程、应用程序域、托管代码、元数据等。

    进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:
    简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
    线程的划分尺度小于进程,使得多线程程序的并发性高。
    另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
    线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
    从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
    线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
    一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行
     
    进程和线程的主要差别在于它们是不同的操作系统资源管理方式。 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程 之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于 一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。如果有兴趣深入的话,建议看看《现代操作系统》或者《操作系统的设计与实现》。对就个问题说得比较清楚。
      
     
      我们知道,进程是操作系统用于隔离众多正在运行的应用程序的机制。 在.Net之前,每一个应用程序被加载到单独的进程中,并为该进程指定私有的虚拟内存。进程不能直接访问物理内存,操作系统通过其它的处理把这些虚拟内存映射到物理内存或IO设 备的某个区域,而这些物理内存之间不会有重叠,这就决定了一个进程不可能访问分配给另一个进程的内存。相应地,运行在该进程中的应用程序也不可能写入另一 个应用程序的内存,这确保了任何执行出错的代码不会损害其地址空间以外的应用程序。在这种机制下,进程作为应用程序之间一个独立而 安全的边界在很大程度上提高了运行安全。

      进程的缺点是降低了性能。许多一起工作的进程需要相互通 信,而进程却不能共享任何内存,你不能通过任何有意义的方式使用从一个进程传递到另一个进程的内存指针。此外,你不能在两个进程间进行直接调用。你必须代之以使用代理,它提供一定程度的间接性。虽然,使用动态连接库dll让所有的组件运行在同一空间,一定程度上可以提高性能,但这些组件相互影响,一个组件 的错误将极有可能导致整个应用程序的崩溃,“dll地狱更是让许多应用程序难以避免。

    应用程序域(AppDomain)
    在.Net中,应用程序有了一个新的边界:应用程序域(以下简称域)。它是一个用于隔离应用 程序的虚拟边界。为了禁止不应交互的代码进行交互,这种隔离是必要的。.Net的应用程序在域层次上进行隔离,一个域中的应用程序不能直接访问另一个域中的代码和数据。这种隔离使得在一个应用程序范围内创建的所有对象都在一个域内创建,确保在同一进程中一个域内运行的代码不会影响其他域内的应用程序,大大 提高了运行的安全。
    .Net结 构中,由于公共语言运行库能够验证代码是否为类型安全的代码,所以它可以提供与进程边界一样大的隔离级别,其性能开销也要低得多。你可以在单个进程中运行 几个域,而不会造成进程间调用或切换等方面的额外开销。这种方法是把任 何一个进程分解到多个域中,允许多个应用程序在同一进程中运行,每个域大致对应一个应用程序,运行的每个线程都在一个特殊的域中。如果不同的可执行文件都 运行在同一个进程空间中,它们就能轻松地共享数据或直接访问彼此的数据。这种代码同运行同一个进程但域不同的类型安全代码一起运行时是安全的。在一个进程 内运行多个应用程序的能力显著增强了服务器的可伸缩性。
    域间通信
    域是.Net 带 来的一个重要改进,它不仅将众多在运行的应用程序隔离开来,还不影响彼此间通信。虽然,公共语言运行库禁止在不同域中的对象之间进行直接调用,但我们可以 复制这些对象,或通过代理访问这些对象。如果以前一种方式,那么对该对象的调用为本地调用。也就是说,调用方和被引用的对象位于同一域中。如果通过代理 访问对象,调用方和被引用的对象位于不同的域中,对该对象的调用被视为远程调用,这种情形与两个进程间的调用或两台计算机间的调用结构大致相同。这时,需 要被引用对象的元数据对于两个域均可用,以便.Net即时编译JIT能正确执行。
    域与线程的关系

    .Net中, 线程是公共语言运行库用来执行代码的操作系统构造。在运行时,所有托管代码均 加载到一个域中,由特定的操作系统线程来运行。然而,域和线程之间并不具有一一对应关系。在任意给定时间,单个域中可以执行不止一个线程,而且特定线程也 并不局限在单个域内。也就是说,线程可以跨越域边界,不为每个域创建新线程。当然,在指定时刻,每一线程都只能在一个域中执行。运行库会跟踪所有域中有哪 些线程正在运行。通过调用.Net类库的 Thread.GetDomain 方法,你还可以确定正在执行的线程所在的域。

     

    托管代码 (managed code)   

    公共语言运行库环境(而不是直接由操作系统)执行的代码。托管代码应用程序可以获得公共语言运行库服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。   托管代码是可以使用20多种支持Microsoft .NET Framework的高级语言编写的代码,它们包括:C#, J#, Microsoft Visual Basic .NET, Microsoft JScript .NET, 以及C++。所有的语言共享统一的类库集合,并能被编码成为中间语言(IL)。运行库编译器(runtime-aware compiler)在托管执行环境下编译中间语言(IL)使之成为本地可执行的代码,并使用数组边界和索引检查,异常处理,垃圾回收等手段确保类型的安 全。   在托管执行环境中使用托管代码及其编译,可以避免许多典型的导致安全黑洞和不稳定程序的编程错误。同样,许多不可靠的设计也自动的被增强了安全性,例如 类型安全检查,内存管理和释放无效对象。程序员可以花更多的精力关注程序的应用逻辑设计并可以减少代码的编写量。这就意味着更短的开发时间和更健壮的程序。   简单点说,托管代码是一microsoft的中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译源代码,也就是说托管代码充当着翻译的作用,源代码在运行时分为两个阶段:   1.源代码编译为托管代码;(所以源代码可以有很多种,如VB,C#,J#)   2.托管代码编译为microsoft系统的.net平台专用文件(如类库、可执行文件等)。

     

    元数据用于描述公共语言运行库 (CLR) 在 JIT 编译 Microsoft 中间语言 (MSIL)、加载类、执行代码以及与 COM 传统型或本机领域进行交互时使用的运行库类型(类、接口和值类型)、字段、方法以及内部实现和布局信息。元数据包括在每个 CLR 组件中,并可供运行库、工具和服务使用。

    对元数据的所有操作都通过元数据 API 执行,这些 API 将客户端(工具和服务)与基础数据结构隔离,实现了一种可插入的持久性格式体系结构,这种体系结构允许运行库的二进制表示形式、COM 传统型类型库和其他格式以透明方式出入内存。

    元数据 API 包括发出(即生成)和导入元数据的接口。客户端可通过下列方式发出或导入元数据:

    • 编 译器和工具通过调用“发出”API 发出元数据。元数据在编译和链接过程中发出。在生成组件或应用程序的过程中,RAD 工具将发出元数据。API 向内存中数据结构写入数据并从中读取数据。在保存时,这些内存中结构将被压缩并以二进制格式保存到目标编译单元(.obj 文件)、可执行文件(.exe 文件)或独立元数据二进制文件中。在通过链接多个编译单元来形成 EXE 或 DLL 文件时,“发出”API 将提供相应的方法,用于将每个编译单元中的元数据节合并为一个集成的元数据二进制文件。

    • 在导入元数据时,加载程序及其他运行库工具和服务将调用“导入”API 来获取有关组件的信息,以便可以完成加载和激活等任务。

     

    元数据以非特定语言的方式描述在代码中定义的每一类型和成员。元数据存储以下信息:  
    程序集的说明。   
    标识(名称、版本、区域性、公钥)。   
    导出的类型。   
    该程序集所依赖的其他程序集。   
    运行所需的安全权限。   
    类型的说明。   
    名称、可见性、基类和实现的接口。   
    成员(方法、字段、属性、事件、嵌套的类型)。   
    属性。   
    修饰类型和成员的其他说明性元素。

    元数据的优点

    对于一种更简单的编程模型来说,元数据是关键,该模型不再需要接口定义语言 (IDL) 文件、头文件或任何外部组件引用方法。元数据允许 .NET 语言自动以非特定语言的方式对其自身进行描述,而这是开发人员和用户都无法看见的。另外,通过使用属性,可以对元数据进行扩展。元数据具有以下主要优点:

    自描述文件

      公共语言运行库模块和程序集是自描述的。模块的元数据包含与另一个模块进行交互所需的全部信息。元数据自动提供 COM 中 IDL 的功能,允许将一个文件同时用于定义和实现。运行库模块和程序集甚至不需要向操作系统注册。结果,运行库使用的说明始终反映编译文件中的实际代码,从而提高应用程序的可靠性。

    语言互用性和更简单的基于组件的设计

      元数据提供所有必需的有关已编译代码的信息,以供您从用不同语言编写的 PE 文件中继承类。您可以创建用任何托管语言(任何面向公共语言运行库的语言)编写的任何类的实例,而不用担心显式封送处理或使用自定义的互用代码。

     

  • 相关阅读:
    Android 自定义View手写签名并保存图片
    快速定位iOS线上BUG在哪个控制器崩溃
    最简单的iOS网络请求
    ButterKnife的安装与使用以及ButterKnife右键不显示的大坑
    安卓两个build.gradle的区别
    苹果电脑获取Android Studio的发布版SHA1和开发版SHA1
    AppStore下载Xcode的文件
    webp转png或jpg
    让Xcode日志输出中文
    iOSPush自动隐藏tabbar
  • 原文地址:https://www.cnblogs.com/mumue/p/2558119.html
Copyright © 2011-2022 走看看