返回顶部
首页 > 资讯 > 操作系统 >Linux下文件输入/输出端口的试炼分析
  • 661
分享到

Linux下文件输入/输出端口的试炼分析

2023-06-16 14:06:02 661人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关linux下文件输入/输出端口的试炼分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。文件描述符(File Descriptor)a small, nonnegative in

这篇文章将为大家详细讲解有关linux下文件输入/输出端口的试炼分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

文件描述符(File Descriptor)

a small, nonnegative integer for use in subsequent system calls (read(2), write(2), lseek(2), fcntl(2), etc.) ($man 2 open). 一个程序开始运行时一般会有3个已经打开的文件描述符:

  • 0 :STDIN_FIFLENO,标准输入stdin

  • 1 :STDOUT_FILENO,标准输出stdout

  • 2 :STDERR_FILENO,标准错误stderror

fd原理

  • fd从0开始, 查找最小的未被使用的描述符, 把文件表指针与文件表描述符建立对应关系(VS pid是一直向上涨,满了再回来找)

  • 文件描述符就是一个int, 用于代表一个打开的文件, 但是文件的管理信息不能够不是存放在文件描述符中,当使用open()函数打开一个文件时, OS会将文件的相关信息加载到文件表等数据结构中, 但出于安全和效率等因素的考虑, 文件表等数据结构并不适合直接操作, 而是给该结构指定一个编号, 使用编号来进行操作, 该编号就是文件描述符

  • OS会为每个进程内部维护一张文件描述符总表, 当有新的文件描述符需求时, 会去总表中查找最小的未被使用的描述符返回, 文件描述符虽然是int类型, 但其实是非负整数, 也就是0~OPEN_MAX(当前系统中为1024), 其中0,1,2已被系统占用,分别表示stdin, stdout,stderror

  • 使用close()关闭fd时, 就是将fd和文件表结构之间的对应关系从总表中移除, 但不一定会删除文件表结构, 只有当文件表没有与其他任何fd对应时(也就是一个文件表可以同时对应多个fd)才会删除文件表, close()也不会改变文件描述符本身的整数值, 只会让该文件描述符无法代表一个文件而已

  • duplicate fdVS copy fd:dup是把old_fd对应的文件表指针复制给new_fd, 而不是int new_fd=old_fd

  • UNIX使用三种数据结构描述打开的文件:每个进程中用于描述当前进程打开文件的文件描述符表,表示当前文件状态的文件状态标识表,和用于找到文件i节点(索引节点)的V节点表,Linux中并不使用这种Vnode结构,取而代之的是一种通用的inode结构,但本质没有区别,inode是在读取文件时通过文件系统从磁盘中导入的文件位置

    Linux下文件输入/输出端口的试炼分析 

Linux下文件输入/输出端口的试炼分析

文件描述符标志(File Descriptor Flag)

当下的系统只有一个文件描述符标志close-on-exec,仅仅是一个标志,当进程fork一个子进程的时候,在子进程中调用了exec函数时就用到了该标志。意义是执行exec前是否要关闭这个文件描述符。

  • 一般我们会调用exec执行另一个程序,此时会用全新的程序替换子进程的正文,数据,堆和栈等。此时保存文件描述符的变量当然也不存在了,我们就无法关闭无用的文件描述符了。所以通常我们会fork子进程后在子进程中直接执行close关掉无用的文件描述符,然后再执行exec。但是在复杂系统中,有时我们fork子进程时已经不知道打开了多少个文件描述符(包括Socket句柄等),这此时进行逐一清理确实有很大难度。我们期望的是能在fork子进程前打开某个文件句柄时就指定好:这个句柄我在fork子进程后执行exec时就关闭”。所以就有了 close-on-exec

  • 每个文件描述符都有一个close-on-exec标志。在系统默认情况下,这个标志***一位被设置为0。即关闭了此标志。那么当子进程调用exec函数,子进程将不会关闭该文件描述符。此时,父子进程将共享该文件,它们具有同一个文件表项,也就有了同一个文件偏移量等。

  • fcntl()的FD_CLOEXEC和open()的O_CLOEXEC用来设置文件的close-on-exec,当将close-on-exec标志置为1时,即开启此标志, 此时子进程调用exec函数之前,系统就已经让子进程将此文件描述符关闭。

Note:虽然新版本支持在open时设置CLOEXEC,但是在编译的时候还是会提示错误 - error: ‘O_CLOEXEC’ undeclared (first use in this function)。这个功能需要设置宏(_GNU_SOURCE)打开。

#define _GNU_SOURCE //在源代码中加入
-D_GNU_SOURCE //在编译参数中加入

文件状态标志(File Status Flag)

File status flags 用来表示打开文件的属性,file status flag可以通过duplicate一个文件描述符来共享同一个打开的文件的状态,而file descrptor flag则不行

  • Access Modes: 指明文件的access方式:read-only, write-only,read-write。通过open()设置,通过fcntl()返回,但不能被改变

  • Open-time Flags: 指明在open()执行的时候的操作,open()执行完毕这个flag不会被保存

  • Operating Modes: 影响read,write操作,通过open()设置,但可以用fcntl()读取或改变

open()

//给定一个文件路径名,按照相应的选项打开文件,就是将一个fd和文件连接到一起,成功返回文件描述符,失败返回-1设errno  #include<fcntl.h>  int open(const char *pathname, int flags)  int open(const char *pathname, int flags, mode_t mode)  //不是函数重载,C中没有重载, 是可变长参数列表 //pathname:文件或设备路径 //flags :file status flags=Access mode+Open-time flags+Operating Modes、    

建议锁(Adversory Lock)

限制加,但不限制读写, 所以只对加锁成功才读写的程序有效,用来解决不同的进程 同时对同一个文件的同一个位置 “写”导致的冲突问题

读锁是一把共享锁(S锁):共享锁+共享锁+共享锁+共享锁+共享锁+共享锁

写锁是一把排他锁(X锁):永远孤苦伶仃

释放锁的方法(逐级提高):

  • 将锁的类型改为:F_UNLCK, 再使用fcntl()函数重新设置

  • close()关闭fd时, 调用进程在该fd上加的所有锁都会自动释放

  • 进程结束时会自动释放所有该进程加过的文件锁

Q:为什么加了写锁还能gedit或vim写???

A:可以写, 锁只可以控制能否加锁成功, 不能控制对文件的读写, 所以叫”建议”锁, 我加了锁就是不想让你写, 你非要写我也没办法. vim/gedit不通过能否加锁成功来决定是否读写, 所以可以直接上

Q: So如何实现文件锁控制文件的读写操作????

A:可以在读操作前尝试加读锁, 写操作前尝试加写锁, 根据能否加锁成功决定能否进行读写操作

int fd=open("./a.txt",O_RDWR);                  //得到fd  if(-1==fd)     perror("open"),exit(-1);struct flock lock={F_RDLCK,SEEK_SET,2,5,-1};    //设置锁   //此处从第3个byte开始(包含第三)锁5byte  int res=fcntl(fd,F_SETLK,&lock);                //给fd加锁  if(-1==res)     perror("fcntl"),exit(-1);

ioct1()

这个函数可以实现其他文件操作函数所没有的功能,大多数情况下都用在设备驱动程序里,每个设备驱动程序可以定义自己专用的一组ioctl命令,系统则为不同种类的设备提供通用的ioctl命令

//操作特殊文件的设备参数,成功返回0,失败返回-1设errno  #include <sys/ioctl.h>  int ioctl(int d, int request, ...); //d:an open file descriptor.//request: a device-dependent  request  code

close()

//关闭fd,这样这个fd就可以重新用于连接其他文件,成功返回0,失败返回-1设errno  #include <unistd.h>  int close(int fd);
#include <unistd.h> #include<stdlib.h>  int res=close(fd); if(-1==res)         perror("close"),exit(-1);

关于“Linux下文件输入/输出端口的试炼分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: Linux下文件输入/输出端口的试炼分析

本文链接: https://lsjlt.com/news/283957.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Linux下文件输入/输出端口的试炼分析
    这篇文章将为大家详细讲解有关Linux下文件输入/输出端口的试炼分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。文件描述符(File Descriptor)a small, nonnegative in...
    99+
    2023-06-16
  • Linux输入输出与文件
    1. 基于文件指针的文件操作(缓冲) linux中对目录和设备的操作都是文件操作,文件分为普通文件,目录文件,链接文件和设备文件。 1.1. 文件的创建,打开与关闭 原型为: #inclu...
    99+
    2022-06-03
    Linux
  • Ruby迭代器及文件的输入与输出实例代码分析
    这篇文章主要介绍“Ruby迭代器及文件的输入与输出实例代码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Ruby迭代器及文件的输入与输出实例代码分析”文章能帮助大家解决问题。Ruby 迭代器简单...
    99+
    2023-07-06
  • C++输入和输出流的示例分析
    这篇文章给大家分享的是有关C++输入和输出流的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。输入和输出流从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准I/O。从磁盘文件输入数据...
    99+
    2023-06-29
  • Ruby迭代器及文件的输入与输出
    目录前言Ruby 迭代器Ruby each 迭代器语法实例Ruby collect 迭代器语法实例Ruby 文件的输入与输出puts 语句实例gets 语句实例putc 语句实例pr...
    99+
    2023-05-15
    Ruby 迭代器输入与输出 Ruby文件输入与输出
  • Java中输入/输出流体系的示例分析
    这篇文章主要介绍Java中输入/输出流体系的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java输入/输出流体系1.字节流和字符流字节流:按字节读取。字符流:按字符读取。字符流读取方便,字节流功能强大,当不...
    99+
    2023-05-30
    java
  • Linux下route命令输出信息的示例分析
    这篇文章主要为大家展示了“Linux下route命令输出信息的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux下route命令输出信息的示例分析”这篇文章吧。使用不带任何参数的r...
    99+
    2023-06-17
  • Java IO中字节输入输出流的示例分析
    这篇文章主要介绍Java IO中字节输入输出流的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!讲的是字节输入输出流:InputStream、OutputSteam(下图红色长方形框内),红色椭圆框内...
    99+
    2023-06-26
  • C++ 函数调试详解:如何分析函数的输入和输出参数?
    函数调试时,分析输入参数包括:类型匹配、范围、值和边值检查。输出参数分析包含:返回类型验证、指针有效性、引用有效性、值验证等。实战案例演示了如何测试输入和输出参数的有效性,帮助理解代码错...
    99+
    2024-05-03
    c++ 函数调试 编译错误
  • c语言文件输入输出的方法是什么
    C语言文件的输入输出方法主要通过标准库函数来实现。文件的输入输出主要涉及以下几个函数:1. fopen函数:用于打开一个文件,并返回...
    99+
    2023-08-08
    c语言
  • C++中简单的文本文件输入/输出示例详解
    为了便于理解,我们把cout 用于控制台输出时的一些情况和写入到文本文件的情况进行类比: cout 控制台输出 包含头文件 iostream 头文件 iostream 定义了一个 o...
    99+
    2024-04-02
  • java 对象输入输出流读写文件的操作实例
    java 对象输入输出流读写文件的操作实例java 支持对对象的读写操作,所操作的对象必须实现Serializable接口。 实例代码:package vo; import java.io.Serializable; public cl...
    99+
    2023-05-31
    java
  • Linux 终端中命令输出保存到文件中的方法
    当你在 Linux 终端中运行命令或脚本时,它会在终端中打印输出方便你立即查看。 有时你需要将输出保存到文件中以备将来参考。当然你可以在 Linux 终端中复制和粘贴,但是有更好的方法可以在 Linux 命令行中保存...
    99+
    2022-06-03
    Linux 终端命令保存到文件 linux命令保存到文件 linux 终端命令
  • linux shell数据重定向(输入重定向与输出重定向)详细分析
    在了解重定向之前,我们先来看看linux 的文件描述符。 linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作...
    99+
    2022-06-04
    重定向 数据 详细
  • Linux下端口映射的示例分析
    小编给大家分享一下Linux下端口映射的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!端口映射器可实现端口映射功能,一个主要用途就是可以在局域网的网关上运行本程序,将网关服务器的某个端口映射为局域网中某台机器的某个...
    99+
    2023-06-27
  • 怎么将Linux 终端中命令的输出保存到文件中
    小编给大家分享一下怎么将Linux 终端中命令的输出保存到文件中,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!方法 1:使用重定向将命令输出保存到文件中你可以在 Linux 中使用重定向来达成目的。使用重定向操作符,它会将...
    99+
    2023-06-15
  • 如何将Linux终端中命令输出保存到文件中
    这篇文章主要介绍了如何将Linux终端中命令输出保存到文件中的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何将Linux终端中命令输出保存到文件中文章都会有所收获,下面我们一起来看看吧。方法 1:使用重定向将...
    99+
    2023-06-28
  • Linux中shell脚本输出日志的示例分析
    这篇文章给大家分享的是有关Linux中shell脚本输出日志的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、日志方法简介:#日志名称log="./upgrade.log" ...
    99+
    2023-06-09
  • Linux终端中命令如何输出保存到文件中的方法
    小编给大家分享一下Linux终端中命令如何输出保存到文件中的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!当你在 Linux 终端中运行命令或脚本时,它会在终...
    99+
    2023-06-09
  • 在Linux下用scp复制文件无需输入密码的技巧
    当两台LINUX主机之间要互传文件时可使用SCP命令来实现,建立信任关系之后可不输入密码。把你的本地主机用户的ssh公匙文件复制到远程主机用户的~/.ssh/authorized_keys文件中假设本地主机...
    99+
    2022-06-04
    输入密码 技巧 文件
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作