編程環境中Runtime(運行時)的三個含義

編程環境中Runtime(運行時)的三個含義

轉自:https://www.zhihu.com/question/20607178 知乎答主@doodlewind

三個含義

實際上編程語境中的 runtime 至少有三個含義,分別是:

  • 指「程序運行的時候」,即程序生命周期中的一個階段。例句:「Rust 比 C 更容易將錯誤發現在編譯時而非運行時。
  • 指「運行時庫」,即 glibc 這類原生語言的標準庫。例句:「C 程序的 malloc 函數實現需要由運行時提供。
  • 指「運行時系統」,即某門語言的宿主環境。例句:「Node.js 是一個 JavaScript 的運行時。

下面簡單介紹一下個人的理解。

含義一:程序生命周期中的階段

一個程序從寫好代碼字符串(起點)到跑完退出(終點),有一整套標準化的生命周期(流程),可以被拆分為多個階段。這其中編譯階段是 compile time,鏈接階段是 link time,那運行起來的階段自然就是 run time 了。如果在前面的階段預先做了通常在后面才方便做的事,我們就管這個叫 ahead of time。

注意所謂 ahead of time 其實只是英語口語中的常見詞匯,并不是 AJAX 這種專有的技術概念。比如美軍參謀長在通共電話里說的這句:
If we’re going to attack, I’m going to call you ahead of time. It’s not going to be a surprise.[[1]]1

個人猜測 runtime 這個詞衍生出的定義應該就源于 run time,泛指那些「供代碼運行所需的最基礎的軟件」。下面的兩個定義其實也都沒有超出這個范疇。

作者:doodlewind
鏈接:https://www.zhihu.com/question/20607178/answer/2133648600
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

含義二:運行時庫(runtime library)

怎樣理解 runtime library 呢?要知道 C、C++ 和 Rust 這類「系統級語言」相比于 JavaScript 這類「應用級語言」最大的特點之一,就在于它們可以勝任嵌入式裸機、操作系統驅動等貼近硬件性質的開發——而所謂 runtime library,大致就是這時候你沒法用的東西

回想一下,我們在 C 語言里是怎么寫 hello world 的呢?

#include <stdio.h> // 1int main(void) { // 2printf("Hello World!\n"); // 3
}

這里面除了最后一個括號,每行都和運行時庫有很大關系:

  1. stdio.h 里的符號是 C 標準庫提供的 API,我們可以 include 進來按需使用(但注意運行時庫并不只是標準庫)。
  2. main 函數是程序入口,但難道可執行文件的機器碼一打開就是它嗎?這需要有一個復雜的啟動流程,是個從 _start 開始的兔子洞。
  3. printf 是運行時庫提供的符號。可這里難道不是直接調操作系統的 API 嗎?實際上不管是 OS 的系統調用還是匯編指令,它們都不方便讓你直接把字符串畫到終端上,這些過程也要靠標準庫幫你封裝一下。

在缺少操作系統和標準庫的裸機環境下(例如 Rust 的 no_std),上面的代碼是跑不起來的。而這里的 stdio 只是標準庫的冰山一角,再舉幾個非常常見的例子:

  • 負責數學運算的 math.h:很多精簡指令集或嵌入式的低端 CPU 未必會提供做 sin 和 cos 這類三角函數運算的指令,這時它們需要軟件實現。
  • 負責字符串的 string.h:你覺得硬件和操作系統會內置「比較字符串長度」這種功能嗎?當然也是靠軟件實現啦。
  • 負責內存分配的 stdlib.h:直接通過 mmap這類 OS 系統調用來分配內存是過于底層的,一般也需要有人幫你封裝。分配內存的 malloc 雖然只是一個接受單個參數的函數,它的實現可遠沒有表面上的 API 那么簡單,建議翻一翻 @郭忠明 老師的回答。

換句話說,雖然 C 的 if、for 和函數等語言特性都可以很樸素且優雅地映射(lowering)到匯編,但必然會有些沒法直接映射到系統調用和匯編指令的常用功能,比如上面介紹的那幾項。對于這些臟活累活,它們就需要由運行時庫(例如 Linux 上的 glibc 和 Windows 上的 CRT)來實現。

如果你熟悉 JavaScript 但還不熟悉 C,我還有篇講「C 手動內存管理基礎入門」的教程應該適合你。

我們可以把「應用程序、運行時庫和 OS」三者間的關系大致按這樣來理解:

img

注意運行時庫并不只是標準庫,你就算不顯式 include 任何標準庫,也有一些額外的代碼會被編譯器插入到最后的可執行文件里。比如上面提到的 main 函數,它在真正執行前就需要大量來自運行時庫的輔助,一圖勝千言(具體細節推薦參考 Linux x86 Program Start Up):

img

除了加載和退出這些程序必備的地方以外,運行時庫還可以起到類似前端社區 polyfill 的作用,在程序執行過程中被隱式而「按需」地調用。例如 gcc 的 libgcc 和 clang 的 compiler-rt(后者還被移植成了 Rust 的 compiler-builtins ),這些庫都是特定于編譯器的,我們一般比較少聽到,但其實也很好理解。

舉個例子,我在移植 QuickJS 引擎到索尼 PSP 的時候,發現雖然把 libc 的靜態庫鏈接進來了,但鏈接時始終找不到 __truncdfsf2 這個符號。這非常讓人困惑,因為那個報錯位置的源碼簡單到了這種程度:

// 這是 QuickJS 相應位置的源碼
static double js_math_fround(double a)
{return (float)a;
}

我把這個函數在 .o 目標文件里反匯編以后的結果讀來讀去,也完全沒有看到 __truncdfsf2 這個東西。但其實是這樣的:double 到 float 的轉換并不能由 PSP 的 CPU 指令直接完成(PSP 刻意閹割了對雙精度浮點數的硬件支持),因此編譯 PSP 應用時需要通過軟件實現來兼容,這個軟浮點算法就叫 __truncdfsf2,它本來應該由編譯器在鏈接出可執行文件時自動插入,但我用的 Rust 工具鏈恰好沒有實現它(Issue #327 · compiler-builtins),于是就有了這個報錯。最后我把找來的一個軟浮點函數的代碼貼進來,就可以正確完成鏈接了。這其實也是個人第一次意識到原來所謂「運行時庫」并不僅僅是 stdio.h 里提供的那些符號——哪有什么 include 進來一把梭的歲月靜好,還要有編譯器和運行時替你默默負重前行。

理解問題原因后再去看上面的 C 代碼,可以感受到這里運行時庫所起到的作用,跟 JavaScript 中用于支持新語法的 babel 轉譯產物頗有些相似之處。這還是挺有趣的。

總之,由于系統級語言被設計成既可以用來寫操作系統上的原生應用,也可以用來寫 bare metal 的裸機程序,因此這類語言需要的運行時(runtime)被設計成了可以按需使用的庫(library),于是我們就自然地得到了 runtime library 這個概念。

含義三:運行時系統(runtime system)

上面介紹的運行時庫,主要針對的是 C、C++ 和 Rust 這些「系統級語言」。只要將這個概念繼續推廣到其他高級語言,這時候的「運行時」指的就是 runtime system 了——如果討論某門高級語言的運行時,我們通常是在討論一個更重、更大而全的運行時庫

比如 Java 的運行時是 JRE,C# 的運行時是 CLR。這兩者都相當于一個需要在 OS 上單獨安裝的軟件,借助它們來解釋執行相應語言的程序(編譯出的字節碼)。而對 JavaScript 來說,一般「JS 引擎」是個不帶 IO 支持的虛擬機,需要瀏覽器和 Node 這樣的「JS 運行時」才能讓它控制文件、網絡、圖形等硬件資源而真正實用。這些都是很經典的模型了。

典型的高級語言「運行時系統」里大概需要這些基礎組件:

  • 一個解釋執行字節碼的虛擬機,多半得帶個垃圾回收器。
  • 如果語言是源碼解釋執行,那么需要一個編譯器前端做詞法分析和語法分析。
  • 如果運行時支持 JIT 優化,那么還得藏著個編譯器后端(動態生成機器碼)。
  • IO 相關能力,比如 Node.js 的 fs.readFile 之類。

可以看到相比上面 C 語言的「運行時」,這已經是個復雜的基礎軟件系統了。

稍微再展開一點,注意上面的「運行時」里是不包含應用程序業務邏輯的。那么拿 JavaScript 舉例來說,如果我們把業務邏輯先編譯成字節碼,再把它和運行時一起編譯成一個可執行文件,那不就相當于「直接把 JavaScript 編譯成機器碼」了嗎?QuickJS 就可以這么做,但其實這時候業務邏輯解釋執行的天性不會變——難道真有黑科技能把弱類型的腳本直接靠靜態分析編譯達到系統級語言的水平?這更多地只是概念定義上的話術而已。

因此,理論上任意的弱類型動態語言都可以基于這種形式來 AOT 編譯成「原生機器碼」,你看 Dart、Swift 和 Java 都可以直接編譯成可執行文件,區別只是這個運行時的輕重量級不同——當然實際情況肯定沒有這么理想化,譬如哪怕編譯成了 ARM 機器碼,Flutter 里的 Dart 運行時也必然需要比 C 做更多的類型檢查和 stop the world 的 GC,這都是有成本的。但對于應用層開發來說,能做到這樣已經夠好了。

所以我們甚至可以激進地認為對于 OS 上的應用程序,各種編程語言都是或多或少地需要運行時的,大家只有運行時輕重的區別———「其 實 都 一 樣」。

綜上所述,runtime 在技術討論中有多個含義,我們經常用它作為 runtime library 和 runtime system 的簡稱,因此可能造成一些誤解。

推薦閱讀書目:

  • 《程序員的自我修養》,這本書用了很大篇幅專門講運行時庫,很硬也很有料。
  • 《Node.js:來一打C++擴展》,Node 是理解現代高級語言運行時系統的好例子。
  • 《Javascript二十年》。

參考

  1. Top general was so fearful Trump might spark war that he made secret calls to his Chinese counterpart, new book says https://www.washingtonpost.com/politics/2021/09/14/peril-woodward-costa-trump-milley-china/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532756.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532756.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532756.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

非常不錯的一款html5【404頁面】,不含js腳本可以左右擺動,原生JavaScript實現日歷功能代碼實例(無引用Jq)...

這篇文章主要介紹了原生JavaScript實現日歷功能代碼實例(無引用Jq),文中通過示例代碼介紹的非常詳細&#xff0c;對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下成品顯示&#xff0c;可左右切換月份html 代碼移動端日歷日一二三四五六css代碼*{margin: 0;pa…

12 [虛擬化] 進程抽象;fork,execve,exit

12 [虛擬化] 進程抽象&#xff1b;fork&#xff0c;execve&#xff0c;exit 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1N741177F5?p12 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/8.slides#/ 本講概述 回到“…

計算機應用與基礎實踐怎么考,自考計算機基礎應用科目筆試和實踐性考試怎么考...

自考計算機基礎應用科目筆試和實踐性考試怎么考&#xff1f; 報考自考的考生有些專業的考生會在自己的課程科目中發現計算機基礎應用不僅有理論知識考試還有實踐性考試&#xff0c;那么自考計算機基礎應用科目的筆試和實踐性考試怎么考&#xff1f;自考計算機基礎應用科目筆試怎…

14 [虛擬化] 虛存抽象;Linux進程的地址空間

14 [虛擬化] 虛存抽象&#xff1b;Linux進程的地址空間 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1N741177F5?p14 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/10.slides#/ 本講概述 程序 狀態機&#xff1b;…

瀏覽器是指在用戶計算機上,自考《網頁設計與制作》測試題及答案

自考《網頁設計與制作》測試題及答案學習是一個不斷積累的過程&#xff0c;為幫助考生們更好地復習《與制作》科目知識點&#xff0c;以下是搜索整理的一份自考《網頁設計與制作》測試題及答案&#xff0c;供參考練習&#xff0c;希望對大家有所幫助!想了解更多相關信息請持續關…

Ubuntu 18.04 安裝OpenCV C++

Ubuntu 18.04 安裝OpenCV C 構建并安裝 僅構建核心模塊 # 更新并安裝依賴 # 更新并安裝依賴 sudo apt update && sudo apt install -y cmake g wget unzip# 下載并解壓包 wget -O opencv.zip https://github.com/opencv/opencv/archive/master.zip unzip opencv.zip…

html計算x的y,HTML5畫布:旋轉時計算x,y點

我開發了一個HTML5 Canvas應用程序&#xff0c;它涉及到讀取一個xml文件&#xff0c;該文件描述了需要在畫布上繪制的箭頭&#xff0c;直形和其他形狀的位置。的XML布局的HTML5畫布&#xff1a;旋轉時計算x&#xff0c;y點實施例&#xff1a;如果對象被旋轉它涉及計算一個點的位…

(2021) 20 [虛擬化] 進程調度

(2021) 20 [虛擬化] 進程調度 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p20 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/11.slides#/ 背景 — 機制與策略分離 機制&#xff1a;一個通用的、可定制…

計算機組裝過程英文版,計算機組裝與維護試題及答案(國外英文資料).doc

計算機組裝與維護試題及答案(國外英文資料)計算機組裝與維護試題及答案(國外英文資料)(1) choiceIn the following equipment, the input device is (b)A. b. b. c. c. c. d. d.In Windows 98, the combination of CTRL Alt Del is (c)A. cold start b. heat start c. interr…

make命令及makefile

make命令及makefile 轉自&#xff1a;https://www.ruanyifeng.com/blog/2015/02/make.html Make 命令教程 作者&#xff1a; 阮一峰 日期&#xff1a; 2015年2月20日 代碼變成可執行文件&#xff0c;叫做編譯&#xff08;compile&#xff09;&#xff1b;先編譯這個&#…

局域網中計算機網絡密碼查看,Win10怎么查看電腦上已知的wifi網絡密碼

方法一&#xff1a;網絡和共享中心查詢1、在Windows 10桌面最左下角的【Windwos開始圖標上右鍵】&#xff0c;在彈出的菜單中點擊打開【網絡連接】&#xff0c;如下圖所示。2、在打開的網絡連接設置中&#xff0c;雙擊已經連接的【無線網絡名稱】&#xff0c;在彈出的【WLAN狀態…

(2021) 22 [持久化] 1-Bit的存儲

(2021) 22 [持久化] 1-Bit的存儲 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p22 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/12.slides#/ 背景 回顧 操作系統是什么&#xff1f;一組對象 一組API…

計算機一級試題論述,計算機一級考試理論題及答案要點

計算機一級考試IT1必做題[1]. 著名的計算機科學家尼.沃思提出了________。A&#xff0e;數據結構&#xff0b;算法程序B&#xff0e;存儲控制結構C&#xff0e;信息熵D&#xff0e;控制論[2]. 下面有關掃描儀的敘述中&#xff0c;錯誤的是________。A&#xff0e;分辨率是掃描儀…

(2021) 23 [持久化] I/O設備與驅動

(2021) 23 [持久化] I/O設備與驅動 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p23 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/13.slides#/ 背景 很多人 (你們的同學們、家長們) 都有一個認識&…

計算機考研計劃時間,2019計算機考研時間安排:復習時間規劃

隨著考研競爭越來越激烈&#xff0c;考研復習一定要做好規劃&#xff0c;每天的時間要做好管理&#xff0c;分清輕重緩急&#xff0c;這樣才能高效率復習。管理的5個原則&#xff0c;大家抓緊調整個人復習。小編還為大家精心準備了計算機考研復習資料還有計算機考研報考指導助力…

(2021) 24 [持久化] 文件系統API

(2021) 24 [持久化] 文件系統API 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p24 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/14.slides#/ 背景 回顧 硬件視角&#xff1a;持久化的“層層抽象” 物…

計算機輔助應用的縮寫有什么,計算機輔助設計的英文縮寫是什么

2008-10-09是什么的英文縮寫?BOBO......頭型里的.....其實"BOBO頭"準確的名稱應該是BOB頭。它是娃娃頭的一種。BOB頭有許多變種&#xff0c;標準的類似于櫻桃小丸子的發型&#xff0c;專業發型師把它稱為BOB。最初是由巴黎發型師Antoine 在1909年發明&#xff0c;但…

Linux中的硬鏈接和軟鏈接

Linux中的硬鏈接和軟鏈接 節選自南大蔣炎巖老師操作系統網絡課程筆記&#xff1a;(2021) 24 [持久化] 文件系統API 硬&#xff08;hard&#xff09;鏈接 UNIX文件指針 在UNIX中&#xff0c;文件和目錄完全不是同一個概念&#xff0c;雖然我們平時看著它們仿佛并列地躺在某個…

計算機win10開機音樂,大師傳授win10系統電腦開機總是自動播放音樂的方案

今天小編分享一下win10系統電腦開機總是自動播放音樂問題的處理方法&#xff0c;在操作win10電腦的過程中常常不知道怎么去解決win10系統電腦開機總是自動播放音樂的問題&#xff0c;有什么好的方法去處理win10系統電腦開機總是自動播放音樂呢&#xff1f;今天本站小編教您怎么…

Linux中的tty、pts、pty等概念辨析

Linux中的tty、pts、pty等概念辨析 基本概念 tty、pty、pts、ptmx tty&#xff08;終端設備的統稱&#xff09;&#xff1a;tty一詞源于Teletypes&#xff0c;或teletypewriters&#xff0c;原來指的是電傳打字機&#xff0c;是通過串行線用打印機鍵盤通過閱讀和發送信息的東…