《Linux系统编程(第2版)》——1.3 标准

1.3 标准

UNIX系统编程是门古老的艺术。UNIX编程的基础理念在几十年来一直根深蒂固。但是,对于UNIX系统,变化却是无处不在。各种行为不断变化,特性不断增加。为了使UNIX世界变得有序,标准化组织为系统接口定义了很多套官方标准。虽然存在很多这样的官方标准,但是Linux没有遵循任何一个标准。相反地,Linux致力于和两大主流标准兼容:POSIX和单一UNIX规范(Single UNIX Specification,SUS)。

除了其他内容,POSIX和SUS为类UNIX操作系统定义了一套C API。该C API为兼容的UNIX系统定义了系统编程接口,至少从中抽取出了通用的API集。

1.3.1 POSIX和SUS的历史
在20世纪80年代中期,电气电子工程师协会(IEEE)开启了UNIX系统上的系统级接口的标准化工作。自由软件运动(Free Software Movement)的创始人Richard Stallman建议把该标准命名成POSIX(发音[pahz-icks]),其全称是Portable Operating System Interface(可移植操作系统接口)。

该工作的第一成果是在1988年获得通过的IEEE std 1003.1-1988(简称POSIX 1988)。1990年,IEEE对 POSIX标准进行了修订,通过了IEEE std 1003.1-1990(POSIX 1990)。后续的修订IEEE Std 1003.1b-1993(POSIX 1993或称POSIX.1b)和IEEE Std 1003.1c-1995(POSIX 1995或称POSIX.1c)分别描述了非强制性的实时和线程支持。2001年,这些非强制性标准在POSIX 1990的基础上进行整合,形成单一标准IEEE Std 1003.1-2001(POSIX 2001)。最新的标准IEEE Std 1003.1-2008 (POSIX 2008)在2008年12月发布。所有的核心POSIX标准都简称为POSIX.1,其中2008年的版本为最新版。

从20世纪80年代后期到20世纪90年代初期,UNIX系统厂商卷入了一场“UNIX之战”中,每家厂商都处心积虑地想将自己的UNIX变体定义成真正的“UNIX”操作系统。几大主要的UNIX厂商聚集在了工业联盟The Open Group周围,The Open Group是由开放软件基金会(Open Software Foundation,OSF)和X/Open合并组成。The Open Group提供证书、白皮书和兼容测试。在20世纪90年代初,正值UNIX之战如火如荼,The Open Group发布了单一UNIX规范(SUS)。SUS广受欢迎,很大原因归于SUS是免费的,而POSIX标准成本很高。今天,SUS合并了最新的POSIX标准。

第一个版本的SUS发布于1994年,然后在1997年和2002年分别发布了两个修订版SUSv2和SUSv3。最新的SUSv4在2008年发布。SUSv4修订结合了IEEE Std 1003.1-2008标准以及一些其他标准。本书将以POSIX标准介绍系统调用和其他接口,原因是SUS是对POSIX的扩展。

1.3.2 C语言标准
Dennis Ritchie和Brian Kernighan的经典著作《C程序设计语言》(Prentice Hall)自1978年首次出版后,一直扮演着非正式的C语言规范的角色。这个版本的C语言俗称K&R C。C语言很快替代了Basic语言和其他语言,成为微型计算机编程的通用语言。因此,为了对当时已经非常流行的C语言进行标准化,美国国家标准协会(ANSI)成立了委员会制定C语言的官方版本。该版本集成了各个厂商的特性和改进,并借鉴了新兴的C++语言的一些经验。这个标准化过程漫长而又艰辛,但是ANSI C在1989年最终顺利完成。1990年,国际标准化组织(ISO)基于ANSI C做了一些有效修改,批准了ISO C90。

1995年,ISO发布了新版的C语言标准ISO C95,虽然该标准很少被执行。在1999年,对C语言做了很多修订,形成了ISO C99标准,它引入了很多新的特征,包括inline函数、新的数据类型、变长数组、C++风格的注释以及新的库函数。该标准的最新版本是ISO C11,该版本最重要的功能是格式化的内存模型,支持跨平台的线程可移植性。

对于C++,ISO标准化进展却非常缓慢。经过几年的发展以及非向前兼容的编译器的发布,通过了第一代C++标准ISO C98。虽然该标准极大地提高了编译器之间的兼容性,但在某些方面限制了一致性和可移植性。2003年通过了ISO C++03标准。它修复了编译器开发人员遇到的一些bug,但是没有用户可见的变化。下一个是目前最新的ISO标准C++11(之前的版本都是C++0x,C++11意味着该版本发布更令人期待),有更多的语言和标准的库附加组件及改进——由于修改非常多,很多人建议C++11作为一门不同的语言,和之前的C++版本区别开。

1.3.3 Linux和标准
正如前面所述,Linux旨在达到兼容POSIX和SUS。SUSv4和POSIX 2008描述了Linux提供的接口,包括支持实时(POSIX.1b)和线程(POSIX.1c)。更重要的是,Linux努力与POSIX与SUS需求兼容。一般来说,如果和标准不一致,就认为是个bug。人们认为Linux与POSIX.1和SUSv3兼容,但是由于没有经过POSIX或SUS的官方认证(尤其是Linux的每次修订),所以无法官方宣布Linux兼容POSIX或SUS。

关于语言标准,Linux很幸运。gcc C编译器兼容ISO C99,而且正在努力支持C11。g++ C++编译器兼容ISO C++03,正在努力支持C++11。此外,gcc和g++_实现了C语言和C++语言的扩展。这些扩展统称为GNU C,在附录A中有相关描述。

Linux的前向兼容做得不是很好[1],虽然近期这方面已经好多了。接口是通过标准说明的,如标准的C库,总是可以保持源码兼容。不同版本之间的二进制代码兼容是由glibc来保证的。由于C语言是标准化的,gcc总是能够准确编译合法的C程序,尽管gcc相关的扩展可能会废弃掉甚至从新的gcc发布版本中删除。最重要的是,Linux内核保证了系统调用的稳定性。一旦系统调用是在Linux内核的稳定版本上实现的,它就不会改变了。

在各种Linux发布版中,Linux标准规范(Linux Standard Base,LSB)对大部分的Linux系统进行了标准化。LSB是几大Linux厂商在Linux基金会(前身是自由标准组织)推动下的联合项目。LSB扩展了POSIX和SUS,添加了一些自己的标准;它尝试提供二进制标准,支持目标代码在兼容系统上无需修改即可运行。大多数Linux厂商都在一定程度上遵循了LSB标准。

1.3.4 本书和标准
本书有意避免对任何标准的介绍“夸夸其谈”。大多数情况下,UNIX系统编程相关的书籍都不应该浪费篇幅探讨以下内容:如某个接口在不同标准下行为有何不同,特定的系统调用在各个系统上的实现情况,以及类似的口舌之战。本书仅涉及在现代Linux系统上的系统编程,它是通过最新版本的Linux内核(3.9)、gcc编译器(4.8)和C库(2.17)来实现的。

因为系统接口通常是固定不变的(Linux内核开发人员尽力避免破坏系统调用接口),并且支持一定程度的源码和二进制兼容性。因此,我们可以深入探索Linux系统接口的细节,不必关心与各种其他的UNIX系统和标准的兼容性问题。专注于探讨Linux也使得本书能够深入探讨Linux最前沿的,并且在未来很长时间依然举足轻重的接口。本书阐述了Linux的相关知识,一些组件如gcc和内核的实现和行为,从专业角度洞察Linux的最佳实践和优化技巧。

时间: 2024-08-02 18:03:18

《Linux系统编程(第2版)》——1.3 标准的相关文章

linux系统编程基础(四) C标准库IO缓冲区和内核缓冲区的区别

1.C标准库的I/O缓冲区 UNIX的传统 是Everything is a file,键盘.显示器.串口.磁盘等设备在/dev 目录下都有一个特殊的设备文件与之对应,这些设备文件也可以像普通文件(保存在磁盘上的文件)一样打开.读.写和关闭,使用的函数接口是相同的.用户程序调用C标准I/O库函数读写普通文件或设备,而这些库函数要通过系统调用把读写请求传给内核 ,最终由内核驱动磁盘或设备完成I/O操作.C标准库为每个打开的文件分配一个I/O缓冲区以加速读写操作,通过文件的FILE 结构体可以找到这

linux系统编程基础(二) C 标准IO 库函数与Unbuffered IO函数

先来看看C标准I/O库函数是如何用系统调用实现的. fopen(3) 调用open(2)打开指定的文件,返回一个文件描述符(就是一个int 类型的编号),分配一个FILE 结构体,其中包含该文件的描述符.I/O缓冲区和当前读写位置等信息,返回这个FILE 结构体的地址. fgetc(3) 通过传入的FILE *参数找到该文件的描述符.I/O缓冲区和当前读写位置,判断能否从I/O缓冲 区中读到下一个字符,如果能读到就直接返回该字符,否则调用read(2),把文件描述符传进 去,让内核读取该文件的数

《Linux系统编程(第2版)》——第1章 入门和基本概念 1.1 系统编程

第1章 入门和基本概念 摆在你面前的是一本关于系统编程的书,你将在本书中学习到编写系统软件的相关技术和技巧.系统软件运行在系统的底层,与内核和系统核心库进行交互.常见的系统软件包括Shell.文本编辑器.编译器.调试器.核心工具(GNU Core Utilities)以及系统守护进程.此外,网络服务.Web服务和数据库也属于系统软件的范畴.这些程序都是基于内核和C库实现的,可以称为"纯"系统软件.相对地,其他软件(如高级GUI应用),很少和底层直接交互.有些程序员一直在编写系统软件,而

《Linux系统编程(第2版)》——导读

前言 这本书是关于Linux上的系统编程."系统编程"是指编写系统软件,其代码在底层运行,直接跟内核和核心系统库对话.换句话说,本书的主题是Linux系统调用和底层函数说明,如C库定义的函数. 虽然已经有很多书探讨UNIX上的系统编程,却很少有专注于探讨Linux方面的书籍,而探讨最新版本的Linux以及Linux特有的高级接口的书籍更是凤毛麟角.此外,本书还有一个优势:我为Linux贡献了很多代码,包括内核及其上面的系统软件.实际上,本书中提到的一些系统调用和系统软件就是我实现的.因

《Linux系统编程(第2版)》——2.12 结束语

2.12 结束语 本章讨论了Linux系统编程的基础:文件I/O.在Linux这样遵循一切皆文件的操作系统中,了解如何打开.读.写和关闭文件是非常重要的.所有这些操作都是传统的UNIX方式,很多标准都涵盖它们.

《Linux系统编程(第2版)》——1.2 API和ABI

1.2 API和ABI 程序员都希望自己实现的程序能够一直运行在其声明支持的所有系统上.他们希望能在自己的Linux版本上运行的程序也能够运行于其他Linux版本,同时还可以运行在其他支持Linux体系结构的更新(或更老)的Linux版本上. 在系统层,有两组独立的影响可移植性的定义和描述.一是应用程序编程接口(Application Programming Interface,API),二是应用程序二进制接口(Application Binary Interface,ABI),它们都是用来定义

《Linux系统编程(第2版)》——1.4 Linux编程的概念

1.4 Linux编程的概念 本节给出了Linux系统提供的服务的简要概述.所有的UNIX系统,包括Linux,提供了共同的抽象和接口集合.实际上,UNIX本身就是由这些共性定义的,比如对文件和进程的抽象.管道和socket的管理接口等等,都构成了UNIX系统的核心. 本概述假定你对Linux环境很熟悉:会使用shell的基础命令.能够编译简单的C程序.它不是关于Linux或其编程环境的,而是关于Linux系统编程的基础. 1.4.1 文件和文件系统文件是Linux系统中最基础最重要的抽象.Li

《Linux系统编程(第2版)》——1.5 开始系统编程

1.5 开始系统编程 这一章着眼于Linux系统编程的基础概念并从程序员视角探索Linux系统.下一章将讨论基本的文件I/O,这当然包括读写文件,但是由于Linux把很多接口以文件形式实现,因此文件I/O的至关重要性不仅仅是对于文件而言,对于Linux系统的很多其他方面亦是如此. 了解了这些基础知识后,可以开始深入探索真正的系统编程了.我们一起动手吧.

linux系统编程之文件与I/O(六) fcntl函数与文件锁

一.fcntl函数 功能:操纵文件描述符,改变已打开的文件的属性 int fcntl(int fd, int cmd, ... /* arg */ ); cmd的取值可以如下: 复制文件描述符 F_DUPFD (long) 设置/获取文件描述符标志 F_GETFD (void) F_SETFD (long) 设置/获取文件状态标志 F_GETFL (void) F_SETFL (long) 获取/设置文件锁 F_GETLK F_SETLK,F_SETLKW 其中复制文件描述符可参见<linux系

LINUX系统编程 LINUX 虚拟内存

LINUX 虚拟内存 以32位操作系统为例子,因为64位系统虚拟地址过大为2^64,32位仅仅为2^32=4G更利于描述,但是原理东西都一样 这首先要从程序和进程之间的关系开始,我们一般写好一段C\C++代码编译后仅仅为可执行文件假设为a.out,我们 运行a.out的时候,这个才叫进程,进程是OS级别抽象的实体(PCB task_struct结构体),为程序运行进行各种检查和 系统资源分配,一个PCB包含部分信息如下: (摘至刑文鹏LINUX系统编程讲义) * 进程id.系统中每个进程有唯一的