运行时系统

计算机编程中,运行时系统运行时环境是一个子系统,都存在于创建程序的计算机中,以及在打算运行程序的计算机中。该名称来自编译的时间运行时划分,与编译的语言相似,该语言类似地区分了创建程序(编译)中涉及的计算机过程及其在目标机器中的执行(运行时间)。

大多数编程语言都有某种形式的运行时系统,可提供程序运行的环境。此环境可能会解决许多问题,包括管理记忆管理,程序如何访问变量过程之间传递参数的机制,与操作系统的接口以及其他方式。编译器根据特定的运行时系统做出假设,以生成正确的代码。通常,运行时系统将对设置和管理堆栈负有某种责任,并且可能包括诸如垃圾收集线程或其他动态功能之类的功能。

概述

每个编程语言都指定执行模型,许多编程语言在运行时系统中至少实现了该模型的一部分。运行时系统行为的一个可能定义是“任何不直接归因于程序本身的行为”。该定义包括在函数调用之前将参数放在堆栈上,并行执行相关行为和磁盘I/O

根据这个定义,从本质上讲,每种语言都有一个运行时系统,包括编译语言解释语言嵌入式域特异性语言。即使是API启用的独立执行模型,例如PthreadsPOSIX线程),也具有实现执行模型行为的运行时系统。

关于运行时系统的大多数学术论文都集中在并行运行时系统的实现细节上。并行运行时系统的一个显著示例是CILK ,这是一种流行的并行编程模型。创建了原始时间的工具包,以简化并行运行时系统的创建。

除了执行模型行为外,运行时系统还可以执行支持服务,例如类型检查调试代码生成优化

与运行时系统类似的概念之间的比较
类型 描述 例子
运行环境 为执行代码提供环境的软件平台 Node.js.NET框架
引擎 运行时环境的组件通过编译或解释来执行代码 网络浏览器中的JavaScript引擎Java虚拟机
口译员 逐行读取和执行代码的引擎类型,而无需事先编译整个程序 Cpython解释器, Ruby MRI ,JavaScript(在某些情况下)
JIT口译员 在运行时将代码动态编译到机器指令中的解释器类型,优化代码以更快地执行 V8PYPY口译员

与运行时环境有关

运行时系统也是运行程序与运行时环境进行交互的网关。运行时环境不仅包括可访问的状态值,还包括程序在执行过程中可以进行交互的活动实体。例如,环境变量是许多操作系统的功能,并且是运行时环境的一部分。运行程序可以通过运行时系统访问它们。同样,磁盘或DVD驱动器等硬件设备是程序可以通过运行时系统进行交互的活动实体。

运行时环境的一种独特应用是在操作系统中的使用,允许其运行。换句话说,从引导到降低电源,整个操作系统仅专用于该运行时环境中运行的应用程序。试图运行的任何其他代码或应用程序中的任何故障都会破坏运行时环境。破坏运行时环境会破坏操作系统,停止所有处理并需要重新启动。如果启动来自仅读取的内存,则会创建一个非常安全,简单,单误解系统。

这种直接捆绑的运行时系统的示例包括:

  • 在1983年至1984年之间,数字研究为IBM PC提供了几项业务和教育应用程序,该应用程序与Speedstart CP/M-86捆绑在一起的可引导的软盘,这是CP/M-86作为运行时环境的简化版本。
  • Ventura Publisher (1986-1993), Artline (1988–1991), TimeWorks Publisher (1988-1991)和ViewMax (1990-1992)的一些独立版本(TimeWorks Publisher(TimeWorks Publisher)(1988–1991)包含数字研究的特殊运行时版本作为运行时环境
  • 在1990年代后期, JP软件的命令行处理器4DOS可以选择在特殊的运行版本中可用。

例子

C语言的运行时系统是编译器插入可执行图像中的一组特定指令。除其他外,这些指令管理过程堆栈,为本地变量创建空间,然后将函数调用参数复制到堆栈顶部。

通常没有明确的标准来确定哪些语言行为是运行时系统本身的一部分,哪些可以由任何特定源程序确定。例如,在C中,堆栈的设置是运行时系统的一部分。它不是由单个程序的语义确定的,因为该行为在全球范围内不变:它掌握了所有执行。这种系统的行为实现了语言的执行模型,而不是实现特定程序的语义(其中文本直接转换为计算结果的代码)。

特定程序的语义与运行时环境之间的这种分离是由编译程序的不同方式反映的:将源代码编译到包含所有功能的对象文件,而不是将整个程序编译为可执行的二进制文件。该对象文件将仅包含与随附功能相关的汇编代码,而可执行二进制文件将包含实现运行时环境的其他代码。一方面,对象文件可能缺少从运行时环境中通过链接解决的信息。另一方面,对象文件中的代码仍然取决于运行时系统中的假设。例如,一个函数可以根据运行时环境使用的调用约定读取特定寄存器或堆栈位置的参数。

另一个示例是使用应用程序编程接口(API)与运行时系统进行交互。对该API的调用看起来与通用常规软件库的呼叫相同,但是在呼叫过程中的某个时候,执行模型会更改。运行时系统实现了执行模型与库用语言不同的语言不同。阅读普通库的代码的人将能够通过了解库的写入语言来理解库的行为。但是,阅读调用运行时系统的API代码的人无法理解仅通过知道呼叫的语言写入的语言,在某个时候,通过某种机制,执行模型停止了呼叫的语言的执行模型,然后切换为由运行时实现的执行模型。系统。例如,陷阱指令是切换执行模型的一种方法。这种差异是区分API启动的执行模型(例如Pthreads)和通常的软件库。 Pthreads呼叫和软件库呼叫均通过API调用,但是pthreads行为无法通过呼叫的语言来理解。相反,Pthreads调用将播放外部执行模型,该模型由PTHREADS运行时系统实现(此运行时系统通常是OS内核)。

作为一个极端的例子,可以将物理CPU本身视为特定组装语言的运行时系统的实现。在此视图中,执行模型由物理CPU和内存系统实现。作为一个类比,高级语言的运行时系统本身是使用其他一些语言实现的。这创建了运行时系统的层次结构,CPU本身(实际上是其在微码层或以下)作为最低级别的运行时系统的逻辑。

高级功能

一些编译或解释的语言提供了一个接口,允许应用程序代码直接与运行时系统进行交互。一个示例是Java语言中的Thread类。该类允许代码(由一个线程动画)来执行诸如启动和停止其他线程之类的事情。通常,无法以这种方式访问​​语言行为的核心方面,例如任务调度资源管理

运行时系统实现的高级行为可能包括诸如屏幕上绘制文本或建立Internet连接之类的任务。通常情况下,操作系统也提供此类行为,并且在可用时,运行时系统将作为抽象层实现,该抽象层将运行时系统调用转化为操作系统的调用。这隐藏了不同操作系统提供的服务的复杂性或变化。这也意味着OS内核本身可以视为运行时系统,并且可以将OS行为的OS呼叫集视为与运行时系统的交互。

在限制中,运行时系统可以提供诸如P代码机虚拟机之类的服务,甚至隐藏了处理器的指令集。这是遵循许多解释的语言,例如AWK ,以及Java等某些语言,这些语言旨在将其编译到某些与机器无关的中间表示代码(例如bytecode )中。这种安排简化了语言实施的任务及其对不同机器的适应性,并提高了复杂语言特征(例如反射)的效率。它还允许在任何机器上执行相同的程序,而无需明确的重新编译步骤,这一功能自全球网络扩散以来变得非常重要。为了加快执行速度,某些运行时系统将恰当的汇编功能汇编为机器代码。

运行时系统的一个现代方面是平行执行行为,例如pthreads中的静音构建体和OpenMP中的平行部分构造所表现出的行为。具有这种并行执行行为的运行时系统可以根据原始方法进行模块化

历史

运行时系统的显著早期示例是基本LISP的口译员。这些环境还包括一个垃圾收集器福斯是一种旨在将其编译成中间表示代码的语言的早期示例;它的运行时系统是一台虚拟机,可以解释该代码。唐纳德·诺斯(Donald Knuth)混音计算机是另一个流行的(如果理论上的话)。

在支持动态内存分配的C和后来的语言中,运行时系统还包括一个管理程序存储池的库。

面向对象的编程语言中,运行时系统通常还负责动态类型检查和解决方法参考。

也可以看看