首页 > 其他分享 >[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc

时间:2022-11-03 23:05:55浏览次数:95  
标签:调用 可移植 glibc 中间件 Unix POSIX ---------------------- 库函数


目录

​​第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。

包括:

  1. 美国加州大学伯克利分校的Unix4.xBSD(Berkeley Software Distribution)。
  2. 贝尔实验室发布的自己的版本,称为System V Unix。
  3. 其他厂商的版本,比如Sun Microsystems的Solaris系统,则是从这些原始的BSD和System V版本中衍生而来。

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_unix

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 支持好。

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_Linux_02

第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 系统调用与库函数的关系

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_Libc_03

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_unix_04

如上图所示:

  1. 归属不同:库函数是语言或应用程序的一部分,而系统调用是内核提供给应用程序的接口,属于系统的一部分
  2. 地址空间不同:库函数在用户地址空间执行,系统调用是在内核地址空间执行,库函数运行时间属于用户时间,系统调用属于系统时间,库函数开销较小,系统调用开销较大
  3. 依赖性不同:系统调用依赖于平台,库函数并不依赖
  4. 库函数是应用程序和库函数之间一座桥梁。

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_平台软件_05

2.3 程序的可移植性及其本质

那么目标代码和启动代码是怎么生成的呢? 答案是编译器。

编程语言编写的程序首先要被编译器编译成目标代码(0、1代码),然后在目标代码的前面插入启动代码,最终生成了一个完整的程序。

要注意的是,程序中为访问特定设备(如显示器)或者操作系统(如windows xp 的API)的特殊功能而专门编写的部分通常是不能移植的。

综上所述,一个编程语言的可移植性取决于

  1. 不同平台编译器的数量
  2. 对特殊硬件或操作系统的依赖性

移植是基于操作系统的。

(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等。

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_Linux_06

printf函数执行过程中,程序运行状态切换如下:

用户态–>系统调用–>内核态–>返回用户态

printf函数、glibc库和系统调用在系统中关系图如下:

[架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc_平台软件_07

第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项) 

<cpio.h> ---------------------- cpio归档值
<dlfcn.h> ---------------------- 动态链接
<fmtmsg.h> ---------------------- 消息显示结构
<ftw.h> ---------------------- 文件树漫游
<iconv.h> ---------------------- 代码集转换实用程序
<langinfo.h> ---------------------- 语言信息常量
<libgen.h> ---------------------- 模式匹配函数定义
<monetary.h> ---------------------- 货币类型
<ndbm.h> ---------------------- 数据库操作
<nl_types.h> ---------------------- 消息类别
<poll.h> ---------------------- 轮询函数
<search.h> ---------------------- 搜索表
<strings.h> ---------------------- 字符串操作
<syslog.h> ---------------------- 系统出错日志记录
<ucontext.h> ---------------------- 用户上下文
<ulimit.h> ---------------------- 用户限制
<utmpx.h> ---------------------- 用户帐户数据库
<sys/ipc.h> ---------------------- IPC
<sys/msg.h> ---------------------- 消息队列
<sys/resource.h> ------------------- 资源操作
<sys/sem.h> ---------------------- 信号量
<sys/shm.h> ---------------------- 共享存储

<sys/statvfs.h> ---------------------- 文件系统信息
<sys/time.h> ---------------------- 时间类型
<sys/timeb.h> ---------------------- 附加的日期和时间定义
<sys/uio.h> ---------------------- 矢量I/O操作

(4)POSIX标准定义的可选头文件(8项) 

<aio.h> ---------------------- 异步I/O
<mqueue.h> ---------------------- 消息队列
<pthread.h> ---------------------- 线程
<sched.h> ---------------------- 执行调度
<semaphore.h> ---------------------- 信号量
<spawn.h> ---------------------- 实时spawn接口
<stropts.h> ---------------------- XSI STREAMS接口
<trace.h> ---------------------- 时间跟踪
 

标签:调用,可移植,glibc,中间件,Unix,POSIX,----------------------,库函数
From: https://blog.51cto.com/u_11299290/5821304

相关文章

  • SQL库函数
    一、字符串函数 1.删除字符、添加字符 trim(str) :去掉两侧空格 ltrim(str) :去掉左侧空格 rtrim(str) :去掉右侧空格 trim( 位置, ......
  • SQL库函数
     一、字符串函数 1.删除字符、添加字符 trim(str) :去掉两侧空格 ltrim(str) :去掉左侧空格 rtrim(str) :去掉右侧空格 trim(位置,'去掉谁......
  • django中间件以及自定义中间件
    middleware中间件就是在目标和结果之间进行的额外处理过程,在Django中就是request和response之间进行的处理,相对来说实现起来比较简单,但是要注意它是对全局有效的,可以在全......
  • 【RabbitMQ】1-linux下安装消息中间件RabbitMQ
    版本要求消息中间件RabbitMQ,安装本身没什么难点,要注意的是它依赖的Erlang的版本。版本不支持,安装后启动时会报错:escript:exceptionerror:undefinedfunctionrabbitmq......
  • 如何解决何避免多个C/C++动态库函数同名冲突
    前言现在的开发节奏越来越快,有大量现成的库来方便我们的开发者来使用,避免重复造轮子,而且有很多有生命力的开源社区。当然在使用过程中,你可能为这样的场景而头痛:你的项目中用......
  • web服务器12 中间件函数
    //1,导入expressconstexpress=require('express')constapp=express()//3定义一个中间件//constmw=(req,res,next)=>{//console.log('中间件');//......
  • [单片机框架][os层] RTX5 中间件 公共函数
    KeilRTX5是一种免版税、确定性、全功能的实时操作系统,它实现了CMSIS-RTOSAPIv2,这是一种适用于基于Cortex-M处理器的设备的通用RTOS接口。功能包括定期激活定时器功......
  • vue中间件
    .env.development//部署(文件名).env.production//生产前(文件名)${process.env.VUE_APP_UR}//获取值写一个中间件在写前后台分离的时候肯定是需要发起各种求情......
  • 中间件
    1、含义中间件(Middleware)处于操作系统和应用程序之间的软件。中间件=平台+通信:通常会将一组中间件集成一个平台,且必须包含一个通信中间件(因此只有分布式系统中才......
  • 从中间件团队窃取了这个组件,见识到了编码能力的天花板!!
    大家好,我是陶朱公Boy,又跟大家见面了。前言今天跟大家分享一款基于“生产者消费者模式”下实现的组件。该组件是作者偶然在翻阅公司一中间件源码的时候碰到的,觉得设计......