C语言中的运行时系统

时间:2017-03-10 21:45:46

标签: c computer-science

根据维基百科,execution model

  

语言规范的一部分,并作为语言实现的一部分实现。

它进一步定义了

  

执行顺序可以静态选择[...]但必须动态选择一小部分,因为执行过程。

     

[...]静态选择通常在编译器中实现,在这种情况下,工作顺序由指令放入可执行二进制文件的顺序表示。然后,动态选择将在语言的运行时系统中实现   运行时系统可以是库,由编译器插入的指令调用,或者运行时系统可以直接嵌入到可执行文件中,例如通过插入分支指令,分支指令动态选择下一步要执行的工作。

维基百科将runtime system指定为

  

任何不直接影响程序工作的行为都是运行时系统行为。该定义包括作为运行时系统的一部分,例如在函数调用之前将参数放入堆栈,磁盘I / O的行为以及与并行执行相关的行为。

另外

  

也是运行程序与运行时环境交互的网关,运行环境不仅包含程序执行期间可访问的状态值,还包含可在程序执行期间与磁盘驱动器和人员交互的活动实体,通过键盘。

它进一步指出,

  

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

我知道必须有某种运行时环境,比如Linux内核,将已编译的可执行文件加载到内存中,启动进程,允许子线程和类似的东西。内核本身是用C编写的,不能被视为C语言的“运行时系统”。但是,它提供了malloc()free()等函数,它们是运行时系统的基本组成部分。

那么C的运行时系统究竟是什么?它的定义是否有任何模糊的定义?它是一个独立内核+编译器的混合体吗?

2 个答案:

答案 0 :(得分:0)

不,内核不提供像malloc()free()这样的函数,尽管这些函数最终依赖于内核提供的内存。

C的运行时系统是C运行时库,由编译器的供应商提供。当您#include <stdio.h>或类似的任何内容时,您指定要使用这些库中的功能。如果仔细查看make过程的链接步骤,您将看到编译器生成的目标文件与C运行时库(也简称为“C runtime”)一起被喜欢,以生成可执行文件

然后,稍后,操作系统将加载并执行您的程序,但操作系统不知道,也不关心您的程序编写的语言,以及它正在使用哪种运行时支持。

答案 1 :(得分:0)

“运行时”和“标准库”之间的界限很模糊,并没有真正达成一致。在特权代码和非特权代码之间,“内核”通常是一条更难的线。不同部分的标记方式也因平台而异,因此无法给出一般性答案。

但是,您可以针对特定系统稍微回答一下这个问题。例如,以下是它在具有GNU工具链的典型Linux系统上的工作方式:

  • 程序代码,编译为一堆*.o个文件并链接到可执行文件中。

  • “C运行时库”。这可以作为一些额外的*.o文件(crt1.ocrti.ocrtn.o)使用,编译器会隐式链接到您的程序中。这个库相当小,只做了两件事。它提供_start,加载argcargv,调用main,并在exit返回时调用main(排序)。该库还调用全局构造函数和析构函数 - 它们通常不存在于C中,但您可以使用语言扩展来创建它们。

  • “C标准库”。这可以作为怪物*.so*.a库使用,编译器会隐式链接到您的程序中。它实现了strcpyatoi之类的纯函数,以及mallocfree等更复杂的系统,还提供了一组系统调用,可以是薄包装器像open这样的Linux系统调用,包括forkclone等更通用系统调用的更复杂包装,或者像gettimeofdayclock_gettime一样可以加速VDSO。

这不是“什么是C运行时”的明确答案,因为开始时并没有真正严格定义“运行时”。但是,在Linux上有一个称为“C运行时库”的库,其他系统上也存在类似的库。如果你搜索它,你通常可以直接阅读源代码,或者你可以反汇编它(它不是很长)。

这将在某些平台上发生变化,例如嵌入式平台,你可能只有一个大的“标准库”,它拥有你需要的一切,而且没有内核。