>> >> >> Reference << << << <<<<<<Ref>>>>>>
>> >> >> Indexer << << << <<<<<<Idx>>>>>>
Matched: 0

Tags

    Categories

      Types

        Top Results

          POSIX & SUS
          M: 2026-04-14 - ljf12825

          POSIX

          上世纪Unix分裂严重,每家公司都有自己的Unix:
          Bell UNIX, BSD, HP-UX, AIX, Solaris…
          两大主流分支是AT&T的System V和伯克利的BSD;它们在系统调用、命令工具、库函数等方面存在许多细微差别
          为一个Unix系统(比如SunOS)写的程序,在另一个Unix系统(比如HP-UX)上可能完全编译不过或者运行异常
          为了解决这个原因,IEEE牵头制定了POSIX标准。它统一了“游戏规则”,告诉操作系统厂商:要提供的接口的标准

          POSIX (Portable Operating System Interface,可移植操作系统接口),是一个由IEEE制定,并被ISO和IEC采纳为国际标准的家族标准编号(ISO/IEC 9945)

          • 目标:解决Unix系统碎片化为题,让为不同Unix系统编写的软件能够很容易地移植到其他Unix系统上,而无需大量重写代码
          • 本质:它是一系列的标准和规范,定义了操作系统应该为应用程序提供哪些接口(API);更工程化,精准化的说法是POSIX定义了用户态的ABI + 行为语义契约

          比如:

          • 文件操作要怎么调
          • 进程怎么创建
          • 信号的语义是什么
          • 线程API怎么命名
          • 错误码应该返回什么
          • 路径语义怎么定义

          简单说,只要代码只调用POSIX规定的函数,不碰特定系统的私有API, 就能在Linux, macOS, FreeBSD, Solaris甚至Windows(通过WSL)上直接编译运行

          内容

          POSIX不仅仅是一个库,它定义了一整套操作系统必须提供的“语言”

          1. 系统调用接口:这是最核心的部分。定义了诸如fork, exec, open, read/write, socket等底层函数应该如何工作
          2. 命令行工具和实用程序:如ls, grep, awk, sed, cp, mv等,它们的选项、行为和输出格式都被标准化了
          3. Shell标准:定义了Shell的基本功能和语法。/bin/sh就是一个POSIX兼容的Shell。Bash, Zsh等是它的超集
          4. 线程接口:pthreads库就是POSIX线程标准的一部分,它定义了如何创建、管理和同步线程
          5. 文件和目录结构:对文件系统的布局提出了一些建议,例如/tmp目录用于存放临时文件,/dev目录存放设备文件等

          意义

          对于开发者而言,理解POSIX有三个立竿见影的好处

          1. 优雅处理跨平台代码:在Linux下使用open()没问题,但如果用了open64()或者直接操作/proc下的非标准文件,移植到macOS就会编译失败。遵循POSIX可以避免这种重写代价
          2. 理解“一切皆文件”的哲学:POSIX规定设备、管道、套接字、普通文件都共用一套读写接口。可以用write()向屏幕输出文字,也能用同一个write()向网络连接发送数据包
          3. 区分Linux和Unix的区别:Linux遵循POSIX标准,但Linux有很多GNU扩展。如grep -P(Perl正则)不是POSIX标准,而gerp -E才是

          实时性与并发

          除了基础文件操作,POSIX还有几个重要的标准子扩展,决定了现代操作系统的底层能力

          • POSIX线程(Pthreads):虽然现在都是用更高层的封装(如C++的std::thread),但底层统一是POSIX定义的线程模型。它规定了互斥锁mutex、条件变量cond的精确语义,避免了不同CPU架构下多线程行为的诡异差异
          • POSIX信号(Signals):定义了SIGINT(^C)和SIGSEGV(段错误)的处理流程。虽然发送信号的机制各系统略有不同,但处理函数的签名void handler(int sig)是统一的
          • POSIX异步I/O(AIO):定义了在后台读写文件而不阻塞主线程的标准接口。虽然Linux实现有其历史缺陷,但这是高性能数据库(如Oracle, PostgreSQL)设计磁盘交互的逻辑基础

          局限性

          POSIX看起来已经很完美了,但现实中仍有很多Linux专用程序,因为以下原因

          • 进程创建的经典分歧:POSIX规定用fork()复制进程。但在Windows原生环境下,由于缺少fork语义,即便是遵循POSIX的Cygwin工具,其进程创建效率也远低于Linux
          • 落后:它不包含select/poll/epoll的现代IO模型(epoll根本不是POSIX),现代线程同步原语(原子操作部分不是POSIX范围),高性能网络API(比如io_uring),现代权限模型(SElinux, AppArmor),容器与namespace(Linux特有)

          POSIX只适合作为“最低共识”,想追求性能,必然越界到“非POSIX平台特性”

          POSIX合规认证

          不是所有类Unix系统都是“完全POSIX兼容”的。认证由The Open Group颁发(持有UNIX商标)

          • macOS:自10.5 Leopard起是Single UNIX Specification认证的UNIX系统(POSIX的超集)
          • Linux:绝大多数发行版没有花钱去做正式认证(太贵且更新太快),但行为上是POSIX兼容的(Linus曾调侃“我们符合标准,除了哪些标准错的地方”)
          • Windows:原生NT内核不兼容POSIX,但WSL1通过系统调用翻译实现了极佳的POSIX模拟,WSL2则直接运行Linux内核

          SUS

          SUS(Single UNIX Specification,单一UNIX规范) 是UNIX操作系统的核心标准集,由The Open Group制定
          POSIX作为最低标准,但POSIX比较宽泛,任何系统都能宣称兼容。SUS是一个更完整,更严格UNIX标准,是POSIX的超集,并且带有官方认证机制
          SUS = POSIX + 一些扩展 + UNIX认证规范

          组成

          SUS不是单一文档,而是以下四部分的统称

          1. Base Definitions(基础定义):Chapter1 ~ Chapter7的man手册内容
          2. System Interfacces(系统接口):Chapter2 & Chapter3(系统调用与C库函数)
          3. Shell and Utilities(Shell与工具):Chapter1命令。例如awk, sed, ls, cp的具体选项行为。这是区分Linux和UNIX的重要细节——例如SUS规定cp -r行为不同于Linux的cp -R

          对比

          SUS与POSIX,Linux的关系

          概念关系类比法律/商标地位
          POSIX教科书大纲仅需声明兼容,无需付费测试
          SUS严格的高考真题必须通过The Open Group官方测试套件(VSX),并付费取得认证
          Linux(LTP/LSB)在家做了高考真题绝大数Linux发行版技术上符合SUSv3,但没有UNIX商标。只有少数极昂贵的Linux(如华为EulerOS, Inspur K-UX)曾经付费获得过UNIX03认证

          Linux的众多发行版迭代速度很快,且大都是社区或组织进行维护,SUS认证的价格不菲,如果每个版本都SUS认证,费用极高且意义不大

          _XOPEN_SOURCE

          对于开发者,SUS最重要的价值体现在_XOPEN_SOURCE这个宏

          当写C/C++代码时,如果希望调用的是SUS标准严格定义的函数(而不是GNU扩展函数),需要定义

          #define _XOPEN_SOURCE 700 // 700代表 SUSv4 / POSIX 2008
          #include <unistd.h>
          

          这会组织编译器暴露仅在Linux上可用的非标准函数(如get_current_dir_name()),强制使用SUS规定的getcwd(),从而确保代码可以零成本移植到AIX、Solaris、macOS
          如果不定义这些宏,你写的代码是glibc扩展代码,不是POSIX代码


          截至2026年,通过SUSv4(UNIX03)认证的主流系统包括

          • macOS(自10.5Leopard起,每一版都是官方认真的UNIX)
          • IBM AIX
          • HP-UX
          • Oracle Solaris

          核心版本

          名称正式编号/发布年对应SUS版本关键特性变化
          POSIX.1-1988IEEE Std 1003.1-1988无(早于SUS)起点。仅定义了C语言系统接口,不含Shell和工具
          POSIX.1-1990ISO/IEC 9945-1:1990国际标准化版本,内容与1988版几乎相同
          POSIX.1b1003.1b-1993实时扩展:信号量、消息队列、共享内存、定时器
          POSIX.1c1003.1c-1995线程扩展:pthread_create,互斥锁,条件变量
          POSIX.1-1996IEEE Std 1003.1-1996SUSv1首次大合并:合并了基本规范 + 实时 + 线程
          POSIX.1-2001IEEE Std 1003.1-2001SUSv3重要分水岭。与SUSv3内容完全相同。Linux内核2.6/glibc的主要对标目标
          POSIX.1-2008IEEE Std 1003.1-2008SUSv4当前主流基准。移除了过时函数(如gethostbyname,引入openat等新接口。macOS、AIX以此认证
          POSIX.1-2017IEEE std1003.1-2008SUSv4勘误维护版,无重大新特性
          POSIX.1-2024IEEE Std 1003.1-2024SUSv5最新。引入_FORTIFY_SOURCE风格的安全函数,pthread_mutex_clocklock,修复fork与多线程的原子性问题

          特殊版本

          • POSIX.2(已废弃):曾经独立规定Shell和工具(如grep, find),1996年后内容全部并入POSIX.1主文档
          • POSIX 1003.1d/e/j:一些从未大规模流行的“实时调度增强”,仅用于航空电子或军工嵌入式

          实际写代码时,不需要记年份,只需要记住Feature Test Macro对应的值

          • _POSIX_C_SOURCE=199309L 包含POSIX.1b(实时信号)
          • _POSIX_C_SOURCE=199506L 包含POSIX.1c(线程)
          • _POSIX_C_SOURCE=200112L POSIX.1-2001(Linux默认版本)
          • _POSIX_C_SOURCE=200809L POSIX.1-2008(macOS默认基础)