Linux基础IO(二)

这篇具有很好参考价值的文章主要介绍了Linux基础IO(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux基础IO(二)

缓冲区
为什么会有缓冲区

其实缓冲区的意义是节省进程进行数据 IO 的时间

怎么理解呢?我来举个例子:

孩子上大学了,学校里的水果又很贵,孩子给家里人说了,家里人知道了要给孩子每隔一段时间送点水果。下面有两个选项:

  • 1.亲自开车给孩子送
  • 2.发快递

相信大家大部分人会选择发快递吧,这样既省时间,又省事。

当然操作系统也是这样做的,它也有自己的缓冲区。当我们刷新用户缓冲区的数据时,并不是直接将数据直接刷新到磁盘或显示器上,而是先刷新到OS缓冲区,然后由操作系统将数据刷新到磁盘或者显示器。

缓冲区刷新策略
  • 无缓冲:缓冲区一出现数据,立即刷新

  • 行缓冲:缓冲区每出现一行数据就刷新一次

  • 全缓冲:缓冲区被填满后再刷新

还有两种方式强制刷新缓冲区:

  • fflush()等函数
  • 进程退出

为什么会有缓冲区刷新策略呢?

因为操作系统要求的是高效:一次写入外设等设备的时间消耗是远小于多次写入外设的效率的。其中时间消耗大部分是在等待外设就绪,例如缓冲区等待磁盘的时间就远小于缓冲区数据写入磁盘的时间,比如10秒时间内。9秒的时间是在等磁盘准备就绪,1秒是在写入数据。

操作系统可是个聪明人,它可不会傻傻的浪费自己宝贵的时间。

我们通过一段代码来加对深缓冲策略的理解:

int main()
{
    printf("aaaaaaaaaaaaaa\n");
    fputs("bbbbbbbbbbbbbb\n", stdout);

    write(1, "xxxxxxxxxxxxxx\n", 14);

    fork();
    return 0;
}

在我们直接运行程序时:

Linux基础IO(二),Linux,linux,c++

但是当我们重定向进文件时:

Linux基础IO(二),Linux,linux,c++

  • 第一种情况是行缓冲,我们每使用的\n都是行缓冲。
  • 第二种情况是全缓冲,因为我们把程序重定向到一个文件中,文件是全缓冲,又因为我们使用fork创建了一个子进程,而进程间互不干扰,所以都会打印一次字母a和字母b。而字母x是系统调用write,我们可以看作系统是没有缓冲区的(其实有,只是我们并不清楚规则)所以只打印一次。
系统有缓冲区吗?

用户写入数据到外设,先将数据写入系统缓冲区,再由系统刷新到外设中。

Linux基础IO(二),Linux,linux,c++

因为操作系统是进行软硬件资源管理的软件,再加上我们之前学过的层级结构图(具体细节请看我之前写过的初识操作系统的文章),用户区的数据要刷新到具体外设必须经过操作系统,所以操作系统是肯定有自己的缓冲区的。

Linux基础IO(二),Linux,linux,c++

文件系统

文件分为磁盘文件和内存文件,我们之前一直说的都是内存文件,下面我们来谈谈磁盘文件。

什么是inode

我们都知道文件=内容+属性,其中内容就是数据,属性就是文件名、创建日期和文件大小等。

我们输入ll命令可以查看当前路径下的文件:

Linux基础IO(二),Linux,linux,c++

文件属性是这样的:

Linux基础IO(二),Linux,linux,c++

我们还可以查看这些文件的inode

[wsj@VM-8-4-centos day03]$ ll -i
//或者
[wsj@VM-8-4-centos day03]$ ls -i -l

Linux基础IO(二),Linux,linux,c++

inode到底是什么呢?

inode是一个保存元信息的结构,且因为系统中有大量的文件,为了区分每个文件,就给每个文件一个inode号,这个inode号就和我们每个人有自己的身份证号一样。

所以说inode是一个文件属性的集合。

软硬链接
软链接

我们可以通过以下命令创建一个软链接:

[---@VM-8-4-centos day03]$ ln -s mycode a_mycode

Linux基础IO(二),Linux,linux,c++

我们通过ls -l -i可以看到软链接的文件和源文件的inode是不同的,而且文件大小也是差异很大的。

Linux基础IO(二),Linux,linux,c++

软链接又叫做符号链接,软链接文件相对于源文件来说是一个独立的文件,它有自己的inode号,但是该文件只包含了源文件的路径名,所以软链接文件的大小要比源文件小得多。

其实软链接就类似于Windows操作系统当中的快捷方式。

所以说,运行源文件和运行快捷方式(软链接)是一样的结果。

Linux基础IO(二),Linux,linux,c++

硬链接
[---@VM-8-4-centos day03]$ ln mycode b_mycode

Linux基础IO(二),Linux,linux,c++

我们通过ls -l -i可以看到软=硬链接的文件和源文件的inode是相同的,而且文件大小差不多一模一样,硬链接个数也从1变成了2。

Linux基础IO(二),Linux,linux,c++

硬连接其实就是文件的一个别名,硬链接个数就是文件别名的个数。

和软连接相比,硬链接的源文件被删除后,硬链接仍然可以执行。

Linux基础IO(二),Linux,linux,c++

硬链接可以让多个不在或者同在一个目录下,能够修改同一个文件,且其中一个修改后,所有与其有硬链接的文件都一起修改了。

热知识

当我们创建一个普通文件时,他的硬链接是1,而我们创建一个目录文件他的硬链接是2,这是为什么?

Linux基础IO(二),Linux,linux,c++

原因是该dir目录下必须有有两个隐藏文件...。它们分别是上级目录和当前目录,这就是我们常看别人用的cd ..的原理。(inode也是相同的)

Linux基础IO(二),Linux,linux,c++

总结
  1. 软链接有独立的inode,硬链接没有。
  2. 软链接不能独立运行,硬链接能独立运行。
  3. 软链接相当于快捷方式,硬链接本质没有创建文件,只是对当前文件的复制加上对原来inode的映射,并写入当前目录。
文件的三个时间
  • Access:最后访问时间
  • Modify:文件最后修改时间
  • Change:属性最后修改时间
[---@VM-8-4-centos day03]$ stat day03.cc

Linux基础IO(二),Linux,linux,c++

一般来说,Modify改变会引起Change一起变。因为修改文件内容时,文件的大小一般也会随之改变。但是Change改变却不会引起Modify改变,因为修改文件属性一般不会影响到文件内容。

使用touch命令可以将文件都更新为最新时间。

Linux基础IO(二),Linux,linux,c++

动静态库
什么是动静态库
  • 动态库:程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。(*.so)
  • 静态库:程序在编译链接的时候把库的代码链接 (拷贝) 到可执行文件中,程序运行的时候将不再需要静态库。(*.a)
怎么理解动静态库
原理

生成一个可执行程序需要经过:预处理、编译、汇编、链接,4个阶段。

最终在汇编完成后就会*.o文件,将这样的经常使用的多个*.o文件组合起来就是一个简单的库。因为当需要使用到这个库中的哪个*.o文件,我们直接进行最后一步链接就行,省去了前3个步骤。

实际上,库都是这样做的。把常用的头文件或者函数调用汇编后组合成一个库,以供大家方便使用。

使用

我们可以通过以下命令查看可执行文件链接的库:

[---@VM-8-4-centos day03]$ ldd mycode

Linux基础IO(二),Linux,linux,c++

我们可以通过ls命令查看libc.so.6库的情况:

[wsj@VM-8-4-centos day03]$ ls /lib64/libc.so.6 -l

Linux基础IO(二),Linux,linux,c++

我们还可以通过以下命令来查看这个库的详细信息:

[---@VM-8-4-centos day03]$ file /lib64/libc-2.17.so

Linux基础IO(二),Linux,linux,c++

我们可以看到这是一个动态库,而且还是一个共享的目标文件库。

我们使用的gcc/g++都是动态链接的,如果想要静态链接,我们要在编译时加上-static

我这边直接加在makefile里:

Linux基础IO(二),Linux,linux,c++

这样我们make生成的就是静态链接的可执行程序了。

Linux基础IO(二),Linux,linux,c++

这可比我们之前生成的动态链接的可执行程序大多了,但是它不依赖其他的库。

Linux基础IO(二),Linux,linux,c++

我们再使用file命令,也能看出它是一个静态链接的可执行程序。

Linux基础IO(二),Linux,linux,c++

制作一个库
前置准备

add.h

#pragma once

#include <stdio.h>

extern int add(int x, int y);

add.c

#pragma once
#include "add.h"
int add(int x, int y)
{
    return x + y;
}

sub.h

#pragma once

#include <stdio.h>

extern int sub(int x, int y);

sub.c

#pragma once
#include "sub.h"

int sub(int x, int y)
{
    return x - y;
}

main.c

#include "add.h"
#include "sub.h"

int main()
{
    int a = 10, b = 20;
    int c = add(a, b);
    int d = sub(a, b);
    printf("%d + %d = %d\n", a, b, c);
    printf("%d - %d = %d\n", a, b, d);
    return 0;
}
自制静态库

首先,我们将它们汇编为可重定向二进制目标文件:

gcc -c *.c -o *.o

Linux基础IO(二),Linux,linux,c++

然后,我们使用以下命令将目标文件打包为静态库:

  • ar命令是gnu的归档工具,常用于打包静态库
  • -r:如果静态库文件当中的目标文件有更新,就用新的目标文件替换旧的目标文件。
  • -c:生成静态库文件。
  • -t:列出静态库中的文件。
  • -v:显示详细的信息。
[---@VM-8-4-centos day03]$ ar -rc liblocal.a add.o sub.o

Linux基础IO(二),Linux,linux,c++

我们可以使用-v-t选项查看生成的静态库的详细信息:

[wsj@VM-8-4-centos day03]$ ar -vt liblocal.a

Linux基础IO(二),Linux,linux,c++

最后,将头文件和生成的静态库联系起来。

[---@VM-8-4-centos day03]$ mkdir -p mymathlib/include
[---@VM-8-4-centos day03]$ mkdir -p mymathlib/lib
[---@VM-8-4-centos day03]$ cp *.h mymathlib/include/
[---@VM-8-4-centos day03]$ cp liblocal.a mymathlib/lib/

Linux基础IO(二),Linux,linux,c++

使用自制的静态库

main.cmymathlib移动到一个新的目录下。

Linux基础IO(二),Linux,linux,c++

使用gcc的选项-I-L生成可执行程序。

  • -I:指定头文件路径
  • -L:指定库文件路径
  • -l:指定路径下的哪一个库
[---@VM-8-4-centos day04]$ gcc -o mycode main.c -I ./mymathlib/include -L ./mymathlib/lib -l local

Linux基础IO(二),Linux,linux,c++

然后,我们正常运行即可。

Linux基础IO(二),Linux,linux,c++

我们也可以将我们的库拷贝到系统目录下,这样系统就可以找到我们使用的库,我们就不用指定路径了:

[---@VM-8-4-centos day04]$ sudo cp mymathlib/include/* /usr/include/
[---@VM-8-4-centos day04]$ sudo cp mymathlib/lib/liblocal.a /lib64/

Linux基础IO(二),Linux,linux,c++

自制动态库

首先生成*.o文件。

  • -fPIC:形成位置无关码
[---@VM-8-4-centos day03]$ gcc -fPIC -c add.c sub.c

Linux基础IO(二),Linux,linux,c++

然后,使用-shared选项打包目标文件为库。

Linux基础IO(二),Linux,linux,c++

最后,将头文件和库联系起来。

[---@VM-8-4-centos day03]$ mkdir -p mymathlib/include
[---@VM-8-4-centos day03]$ mkdir -p mymathlib/lib
[---@VM-8-4-centos day03]$ cp *.h mymathlib/include/
[---@VM-8-4-centos day03]$ cp liblocal.so mymathlib/lib/

Linux基础IO(二),Linux,linux,c++

Linux基础IO(二),Linux,linux,c++

使用自制的动态库

main.cmymathlib移动到同一个目录下。

使用以下命令(和刚才使用静态库基本一样):

[wsj@VM-8-4-centos day04]$ gcc -o mycode main.c -I ./mymathlib/include -L ./mymathlib/lib -l local

Linux基础IO(二),Linux,linux,c++

我们此刻执行后却是无法运行。

Linux基础IO(二),Linux,linux,c++

原因是生成的可执行程序依赖的动态库没有被找到。

Linux基础IO(二),Linux,linux,c++

解决方法:

方法1:将动态库拷贝到系统目录下。

sudo cp mymathlib/lib/liblocal.so /lib64

方法2:添加环境变量

[---@VM-8-4-centos day04]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wsj/bit/day04/mymathlib/lib

Linux基础IO(二),Linux,linux,c++

方法3:配置/etc/ld.so.conf.d/

[---@VM-8-4-centos day04]$ echo /home/wsj/bit/day04/mymathlib/lib > matH.conf
[---@VM-8-4-centos day04]$ sudo cp matH.conf /etc/ld.so.conf.d

Linux基础IO(二),Linux,linux,c++

完成任意一种解决方法后运行即可。

Linux基础IO(二),Linux,linux,c++

感谢您的阅读,欢迎指正。文章来源地址https://www.toymoban.com/news/detail-608607.html

到了这里,关于Linux基础IO(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】:基础IO

    共识原理: 1.文件=属性+内容。 2.文件分为打开文件和未打开文件。 3.打开的文件:进程打开。 4.未打开的文件:在磁盘里存放着。 5.文件打开,必须先被加载到内存。 6.一个进程可以打开多个文件,那么操作系统就必须先描述再组织的对文件进行管理。 fopen打开的文件如果

    2024年02月06日
    浏览(38)
  • Linux之基础IO

    1.即使是空文件也要在磁盘中占用空间,因为文件=文件数据+文件属性,空文件没有文件数据但是仍然有文件属性。 2.因为文件=文件内容+文件属性,所以对文件的操作无非就是对内容/属性的操作。 3.在一个C程序中调用了文件操作函数,如果程序没有被执行这些文件操作函数

    2023年04月18日
    浏览(30)
  • 【Linux】基础IO —— 上

    🎇Linux:基础IO详解 博客主页: 一起去看日落吗 分享博主的在Linux中学习到的知识和遇到的问题 博主的能力有限,出现错误希望大家不吝赐教 分享给大家一句我很喜欢的话: 看似不起波澜的日复一日,一定会在某一天让你看见坚持的意义,祝我们都能在鸡零狗碎里找到闪闪

    2023年04月23日
    浏览(32)
  • 【Linux】基础IO

    操作文件,除了C接口外,我们还可以采用系统接口来进行文件访问,我们来看看如下代码: 读文件 1.1 接口介绍 open man open open 函数具体使用那个,和具体的应用场景有关,如果目标文件不存在,需open创建,第三个参数表示创建文件的默认权限。 1.2 open函数返回值 认识一下

    2023年04月17日
    浏览(28)
  • Linux——基础IO

    目录 C语言文件操作         fprintf​编辑 Linux下的文件操作(文件的系统调用接口)  open open的第三个参数 open的第二个参数 write  read 文件描述符fd 进程与被打开文件的关系(理解的关键) 见见猪跑 fd文件描述符的分配规则 结论 重定向 输入重定向原理  输出重定向原理  d

    2024年02月06日
    浏览(45)
  • Linux 文件-基础IO

    文件=内容+属性 1 所有对文件的操作可分为两类:a 对内容操作 b 对属性操作 2 内容是数据,属性也是数据,存储文件必须既要存储内容,也要存储属性数据    默认文件在磁盘上 3 进程访问一个文件的时候,都要先把这个文件打开    打开前:普通的磁盘文件    打开后:将

    2024年02月22日
    浏览(47)
  • Linux(基础IO详解)

    在基础IO这篇博客中,我们将了解到文件系统的构成,以及缓冲区究竟是个什么东东,我们都知道缓冲区,有时也谈论缓冲区,但不一定真的去深入了解过缓冲区。为什么内存和磁盘交互速度如此之慢?为什么都说Linux中一切皆文件?别急,在这篇博客中,你都会找到答案。此

    2024年02月08日
    浏览(40)
  • Linux中的基础IO

    目录 1、关于C语言中的文件操作符 1.1 C语言中写文件 1.2 C语言读文件 1.3 往显示器上输出信息 1.4 stdin stdout stderr 1.5 打开文件的方式 2、系统文件IO 2.1 写操作文件 2.2 读操作文件、 2.3 open open函数的返回值 2.4 文件描述符 0 1 2 文件描述符的分配规则 2.5 重定向和dup2  3、缓冲区相

    2024年02月10日
    浏览(38)
  • 【Linux】基础IO——文件系统

    磁盘计算机上唯一的一个机械设备,同时它还是外设 机械磁盘很便宜,虽然效率会慢一些,所以企业一般使用机械磁盘,因为便宜 磁盘不仅仅外设,还是一个机械设备(盘片、磁头),所以磁盘一定非常慢 盘片:一片两面,有一摞盘片 磁头:一面一个磁头 一个磁头负责一面的

    2023年04月09日
    浏览(42)
  • 【Linux】 基础IO——文件(下)

    修改test.c文件内容 运行可执行程序, 发现文件描述符返回的是3 但为啥是3,不是0 ,1,2 任何一个进程,在启动的时候,默认会打开当前进程的三个文件: 标准输入、标准输出、标准错误 ——本质都是文件 C语言:标准输入(stdin) 标准输出(stdout) 、标准错误(stderr) ——文件在

    2023年04月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包