目錄
第1章 POSIX(可移植作業系統接口)概述
1.1 什麼是POSIX
1.2 釋出者-IEEE
1.3 标準的下載下傳位置
1.4 标準的起源
1.5 誰遵守這個标準
第2章 POSIX接口的支援方式
2.1POSIX的好處:可移植性
2.3 程式的可移植性及其本質
2.4 示例
第3章 glibc主要功能簡介
3.1 c語言庫概述
3.2 glibc概述
3.3 POSIX标準的C語言頭檔案
第1章 POSIX(可移植作業系統接口)概述
1.1 什麼是POSIX
可移植作業系統接口(英語:Portable Operating System Interface,縮寫為POSIX)。
POSIX是為要在各種UNIX作業系統上運作軟體,而定義的一系列互相關聯的OS API标準的總稱。
1.2 釋出者-IEEE
釋出者為電氣與電子工程師協會(Institute of Electrical and Electronics Engineers),簡稱IEEE。這個協會老牛了【該組織在太空、計算機、電信、生物醫學、電力及消費性電子産品等領域中都是主要的權威】!
其正式稱呼為IEEE Std 1003,而國際标準名稱為ISO/IEC 9945。此标準源于一個大約開始于1985年的項目。POSIX這個名稱是由理查德·斯托曼(RMS)應IEEE的要求而提議的一個易于記憶的名稱。它基本上是Portable Operating System Interface(可移植作業系統接口)的縮寫,而X則表明其對Unix API的傳承。
IEEE,總部位于美國紐約,是一個國際性的電子技術與資訊科學工程師的協會,也是目前全球最大的非營利性專業技術學會。IEEE緻力于電氣、電子、計算機工程和與科學有關的領域的開發和研究,在太空、計算機、電信、生物醫學、電力及消費性電子産品等領域已制定了1300多個行業标準,現已發展成為具有較大影響力的國際學術組織
1.3 标準的下載下傳位置
标準線上位址: http://www.unix.org/version3/online.html 注冊後可以線上閱讀或者下載下傳。
1.4 标準的起源
POSIX是Unix的标準。
1974年,貝爾實驗室正式對外釋出Unix。因為涉及到反壟斷等各種原因,加上早期的Unix不夠完善,于是貝爾實驗室以慷慨的條件向學校提供源代碼,是以Unix在大專院校裡獲得了很多支援并得以持續發展。
于是出現了好些獨立開發的與Unix基本相容但又不完全相容的OS,通稱Unix-like OS。
包括:
- 美國加州大學伯克利分校的Unix4.xBSD(Berkeley Software Distribution)。
- 貝爾實驗室釋出的自己的版本,稱為System V Unix。
- 其他廠商的版本,比如Sun Microsystems的Solaris系統,則是從這些原始的BSD和System V版本中衍生而來。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAnYldHL0FWby9mZvwFN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcV2Zh1Wa9M3clN2byBXLzN3btgHL9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yM4ITNxgTN3YjY3QTMkNjNzYzXzQzMzIjMzAzLcFTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
20世紀80年代中期,Unix廠商試圖通過加入新的、往往不相容的特性來使它們的程式與衆不同。
局面非常混亂,麻煩也就随之而來了。
為了提高相容性和應用程式的可移植性,阻止這種趨勢, IEEE(電氣和電子工程師協會)開始努力标準化Unix的開發,後來由 Richard Stallman命名為“Posix”。
這套标準涵蓋了很多方面,比如Unix系統調用的C語言接口、shell程式和工具、線程及網絡程式設計。
有了這個規範,你就可以調用通用的API了,Linux提供的POSIX系統調用在Unix上也能執行,是以學習Linux的底層接口最好就是了解POSIX标準。
1.5 誰遵守這個标準
首先就是大名鼎鼎的Unix和Linux了,除此之外還有蘋果的作業系統也是Unix-based的。
Windows從WinNT開始就有相容POSIX的考慮。這是因為當年在要求嚴格的領域,Unix地位比Windows高。為了把Unix使用者拉到Windows陣營,被迫支援POSIX。現在Win10對 Linux/POSIX 支援好。
第2章 POSIX接口的支援方式
2.1POSIX的好處:可移植性
Linux下提供兩種方式支援可移植性:
系統調用(system call)和庫函數調用(Library functions)。
(1)系統調用
系統調用是通向作業系統本身的接口,是面向底層硬體的。
通過系統調用,可以使得使用者态運作的程序與硬體裝置(如CPU、磁盤、列印機等)進行互動,是作業系統留給應用程式的一個接口。
(2)庫函數(符合POSIX标準)
庫函數(Library function)是把函數放到庫裡,供别人使用的一種方式。
方法是把一些常用到的函數編完放到一個檔案裡,供不同的人進行調用。一般放在.lib檔案中。
庫函數調用則是面向應用開發的,庫函數可分為兩類,
- 一類是C語言标準規定的庫函數,
- 一類是編譯器特定的庫函數。
(由于版權原因,庫函數的源代碼一般是不可見的,但在頭檔案中你可以看到它對外的接口)。
glibc 是 Linux 下使用的開源的标準 C 庫,它是 GNU 釋出的 libc 庫,即運作時庫。這些基本函數都是被标準化了的,而且這些函數通常都是用彙編直接實作的。
glibc 為程式員提供豐富的 API(Application Programming Interface),這些API都是遵循POSIX标準的,API的函數名,傳回值,參數類型等都必須按照POSIX标準來定義。
POSIX相容也就指定這些接口函數相容,但是并不管API具體如何實作。
2.2 系統調用與庫函數的關系
如上圖所示:
- 歸屬不同:庫函數是語言或應用程式的一部分,而系統調用是核心提供給應用程式的接口,屬于系統的一部分
- 位址空間不同:庫函數在使用者位址空間執行,系統調用是在核心位址空間執行,庫函數運作時間屬于使用者時間,系統調用屬于系統時間,庫函數開銷較小,系統調用開銷較大
- 依賴性不同:系統調用依賴于平台,庫函數并不依賴
- 庫函數是應用程式和庫函數之間一座橋梁。
2.3 程式的可移植性及其本質
那麼目标代碼和啟動代碼是怎麼生成的呢? 答案是編譯器。
程式設計語言編寫的程式首先要被編譯器編譯成目标代碼(0、1代碼),然後在目标代碼的前面插入啟動代碼,最終生成了一個完整的程式。
要注意的是,程式中為通路特定裝置(如顯示器)或者作業系統(如windows xp 的API)的特殊功能而專門編寫的部分通常是不能移植的。
綜上所述,一個程式設計語言的可移植性取決于
- 不同平台編譯器的數量
- 對特殊硬體或作業系統的依賴性
移植是基于作業系統的。
(1)二進制代碼:
我們需要注意一點:基于各種作業系統平台不同,應用程式在二進制代碼級别是不能直接移植的。
(2)OS API源代碼
我們隻能在源代碼層去思考可移植問題,在API層面上由于各個作業系統的命名規範、系統調用等自身原因,在OS API層面上實作可移植也是不大可能的。
(3)C語言函數庫
在各個平台下,我們預設C标準庫中的函數都是一樣的,這樣基本可以實作可移植。
但是對于C庫本身而言,在各種作業系統平台下其内部實作是完全不同的,也就是說C庫封裝了作業系統API在其内部的實作細節。
是以,C語言提供了我們在代碼級的可移植性,即這種可移植是通過C語言這個中間層來完成的。
例如在我們的代碼中下功夫。以下代碼可以幫助我們實作各平台之間的可移植:
#ifdef _WINDOWS_
CreateThread(); //windows下線程的建立
#else
Pthread_create(); //Linux下線程的建立
#endif
對于頭檔案,也使用同樣的預編譯宏來實作。如:
#ifndef _WINDOWS_
#include <windows.h>
#else
#include <thread.h>
#endif
這樣就可以實作代碼的可移植了。在編譯的時候隻要通過#define就可以選擇在那個平台下完成程式的編譯。有c語言庫實作對不同作業系統平台的屏蔽。
綜上所述,我們都是将C,C++等各種語言庫當作中間層,以實作其一定程度上的可移植。如今,語言的跨平台的程式都是以這樣的方式實作的。但是在不同的平台下,仍需要重新編譯。
2.4 示例
如下圖是Linux系統調用的大概流程。
當應用程式調用printf()函數時,printf函數會調用C庫中的printf,繼而調用C庫中的write,C庫最後調用核心的write()。
而另一些則不會使用系統調用,比如strlen, strcat, memcpy等。
printf函數執行過程中,程式運作狀态切換如下:
使用者态–>系統調用–>核心态–>傳回使用者态
printf函數、glibc庫和系統調用在系統中關系圖如下:
第3章 glibc主要功能簡介
3.1 c語言庫概述
glibc和libc都是Linux下的C函數庫:
libc是Linux下的ANSI C函數庫,
glibc是Linux下的GUN C函數庫。
glibc是遵循POSIX标準的C語言函數庫,是以,我們可以通過glibc來了解POSIX接口的主要功能。
3.2 glibc概述
glibc是GNU釋出的libc庫,即c運作庫。glibc是linux系統中最底層的api,幾乎其它任何運作庫都會依賴于glibc。
glibc除了封裝linux作業系統所提供的系統服務外,它本身也提供了許多其它一些必要其他功能服務的實作。
由于glibc囊括了幾乎所有的 UNIX 通行的标準,可以想見其内容包羅萬象。
glibc是一種按照LGPL許可協定釋出的,自由的,公開源代碼的,友善從網絡下載下傳的C的編譯程式。GNU C運作期庫,是一種C函數庫,是程式運作時使用到的一些API集合,它們一般是已預先編譯好,以二進制代碼形式存在Linux類系統中,GNU C運作期庫通常作為GNU C編譯程式的一個部分釋出。
glibc最初是自由軟體基金會(FSF)為其GNU作業系統所寫,但目前最主要的應用是配合Linux核心,成為GNU/Linux作業系統一個重要的組成部分。
3.3 POSIX标準的C語言頭檔案
(1)基本計算
<assert.h> ---------------------- 驗證程式斷言
<complex.h> ---------------------- 支援複數算術運算
<ctype.h> ---------------------- 字元類型
<errno.h> ---------------------- 出錯碼
<fenv.h> ---------------------- 浮點環境
<float.h> ---------------------- 浮點常量
<inttypes.h> ---------------------- 整型格式轉換
<iso646.h> ---------------------- 替代關系操作符宏
<limits.h> ---------------------- 實作常量
<locale.h> ---------------------- 局部類别
<math.h> ---------------------- 數學常量
<setjmp.h> ---------------------- 非局部goto
<signal.h> ---------------------- 信号
<stdarg.h> ---------------------- 可變參數表
<stdbool.h> ---------------------- 布爾類型和值
<stddef.h> ---------------------- 标準定義
<stdint.h> ---------------------- 整型
<stdio.h> ---------------------- 标準I/O庫
<stdlib.h> ---------------------- 實用程式庫函數
<string.h> ---------------------- 字元串操作
<tgmath.h> ---------------------- 通用類型數學宏
<time.h> ---------------------- 時間和日期
<wchar.h> ---------------------- 擴充的多位元組和寬字元支援
<wctype.h> ---------------------- 寬字元分類和映射支援
(2)網絡與檔案
<dirent.h> ---------------------- 目錄項
<fcntl.h> ---------------------- 檔案控制
<fnmatch.h> ---------------------- 檔案名比對類型
<glob.h> ---------------------- 路徑名模式比對類型
<grp.h> ---------------------- 組檔案
<netdb.h> ---------------------- 網絡資料庫操作
<pwd.h> ---------------------- 密碼檔案
<regex.h> ---------------------- 正規表達式
<tar.h> ---------------------- tar歸檔值
<termios.h> ---------------------- 終端I/O
<unistd.h> ---------------------- 符号常量
<utime.h> ---------------------- 檔案時間
<wordexp.h> ---------------------- 字擴充類型
<arpa/inet.h> ---------------------- Internet定義
<net/if.h> ---------------------- socket套接字本地接口
<netinet/in.h> ---------------------- Internet位址族
<netinet/tcp.h> ---------------------- 傳輸控制協定定義
<sys/mman.h> ---------------------- 記憶體管理聲明
<sys/select.h> ---------------------- select函數
<sys/socket.h> ---------------------- 套接字接口
<sys/stat.h> ---------------------- 檔案狀态
<sys/times.h> ---------------------- 程序時間
<sys/types.h> ---------------------- 基本系統資料類型
<sys/un.h> ---------------------- UNIX域套接字定義
<sys/utsname.h> ---------------------- 系統名
<sys/wait.h> ---------------------- 程序控制
(3)POSIX标準定義的XSI擴充頭檔案(26項)