Linux 系统编程(IO)

工具

  • strace: 根据系统调用
  • od -tcx: 查看二进制

函数参数

  • 使用const修改的指针为传入参数
  • 不使用const的指针为传出参数

string操作的函数

  • strtok: 分隔字符串

IO

  • 函数

    • read
    • write
    • fcntl
    • iocntl
    • perror
    • strerror

IO-1

  • 头文件 -> unistd.h, fcntl.h, stdio.h, errno.h

  • open(fd, mode, permission) 函数

    • mode为宏-> O_RDONLY, O_CREAT, O_APPEND, O_TRUNC(会将文件截断, 将文件的大小改成0), O_RDWR, O_BLOCK, O_NONBLOCK, 当有O_CREAT时有第三个参数权限, 要考虑到umask, open函数使用可变参数实现了函数重载
  • read(fd, buf, sizeof(buf))

  • write(fd, buf, ret) // ret是read函数返回的字节数, 0表示达到了文件末尾, -1是异常

  • close(fd)

IO-2

阻塞

  • 在读取终端设备或者网络设备的时候会出现阻塞, 也就是说在读取这些设备的时候可以这些设备并没有数据可读, 程序就会阻塞在这里

  • 默认情况下, open("/dev/tty", O_RDONLY)是阻塞的, 也就是说只有终端有输入才会往下执行程序

  • open函数进行非阻塞读取, 需要借助宏O_NONBLOCK设置位

    • 示例(这里忽略里错误处理)


      int fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);
      int ret = 0;
      char buf[1024];
      char *msg = "try again..."; while (ret = read(fd, buf, sizeof(buf))) {
      if (-1 == ret) {
      // 注意
      if (errno != EAGAIN) {
      // STDOUT_FILENO 是数字1, STDIN_FILENO 是数字0
      perror("error");
      exit(1);
      }
      write(STDOUT_FILENO, msg, strlen(msg));
      sleep(1);
      continue;
      }
      write(STDOUT_FILENO, buf, ret);
      }
    • 在上例中, 如果终端没有数据, 则read函数返回-1, 但是这并不代表着read错误了, 如果没有数据, Linux会将errno这是为EAGAIN, 如果errno不是EAGAIN, 则读取错误

  • 在执行一个程序的时候, 默认会PCB指向的数组指针中会在0, 1, 2下标对应的位置创建file struct, 代表着stdin, stdout, stderr, 所以我们使用终端的时候, 终端已经被打开了, 在上面的程序中, 我们要向实现非阻塞的功能, 需要打开一个已经打开的文件, 这个是不必要的, Linux提供了fcntl函数用于修改已经打开的文件的属性

    • 示例

      // F_GETFL是Get File Flag, 获取文件属性, 文件属性就是一个int类型, 采用bitmap的方式实现保存多个属性
      int ret = 0;
      int flag = fcntl(STDOUT_FILENO, F_GETFL);
      // 将对应的位置1, 也许O_NONBLOCK是000000000000000000001000000
      // |即使加法, 在fnctl内部判断flag是否有O_NONBLOCK属性, 是通过flag & O_NONBLOCK, 如果返回的是1则表示有O_NONBLOCK属性, 0则表示没有
      flag |= O_NONBLOCK;
      char buf[1024];
      char *msg = "try again..."; while (ret = read(STDOUT_FILENO, buf, sizeof(buf))) {
      if (-1 == ret) {
      // 注意
      if (errno != EAGAIN) {
      // STDOUT_FILENO 是数字1, STDIN_FILENO 是数字0
      perror("error");
      exit(1);
      }
      write(STDOUT_FILENO, msg, strlen(msg));
      continue;
      }
      write(STDOUT_FILENO, buf, ret);
      }
  • 移动文件指针(lseek)

    • 三个表示状态的宏: SEEK_SET(文件起始位置), SEEK_CUR(当前位置), SEEK_END(末尾)
    • lseek(fd, offset, macro)返回当前指针到其实位置的偏移量, 可以用来估计文件大小
    • 示例

      int fd = open("./test.txt", O_RDONLY | O_CREAT, 0644);
      // 文件大小
      int offset = lseek(fd, 0, SEEK_END);
      // 追加数据
      write(...);
      close(fd);
示例cp

int main(int argc, char *argv[]) {
char buf[1024] = {'\0'};
int ret = 0;
if (argc < 3) {
printf("Too Few Parameters\n");
return 1;
}
int fd_src = open(argv[1], O_RDONLY);
int fd_dst = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0666);
while ((ret = read(fd_src, buf, sizeof(buf)))) {
write(fd_dst, buf, ret);
}
close(fd_src);
close(fd_dst);
return 0;
}

Linux IO的更多相关文章

  1. 【知乎网】Linux IO 多路复用 是什么意思?

    提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...

  2. Linux IO模型和网络编程模型

    术语概念描述: IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者. 阻塞和非阻塞,是函数/方法的实现方式,即在数据就绪之前是立刻返回还是等待. 以文件IO为例,一个IO读过程是文件 ...

  3. block_dump观察Linux IO写入的具体文件(mysqld)

      一.使用方法: 二.基本原理: 三.总结 很多情况下开发者调测程序需要在Linux下获取具体的IO的状况,目前常用的IO观察工具用vmstat和iostat,具体功能上说当然是iostat更胜一筹 ...

  4. linux io优化

    场景:xml文件解析入库:并备份 问题:磁盘io异常,经常100%busy: linux io优化方法: 1.修改磁盘挂着参数,修改为writeback模式:对于文件读取频繁的可以设置noatime: ...

  5. Linux IO 调度器

    Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交 ...

  6. Linux IO工具 iotop备择方案iopp

    iotop毫无疑问linux IO检测上是一个很好的工具,但苦于要求和内核版本Python版本号.我的很多朋友放弃了.我也是.无意中发现iopp,使用c书面,与此iotop它是一个作用.nice! 一 ...

  7. 【转】linux IO子系统和文件系统读写流程

    原文地址:linux IO子系统和文件系统读写流程 我们含有分析的,是基于2.6.32及其后的内核. 我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里.我 ...

  8. Linux IO时事检测工具iostat

    Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...

  9. Linux IO Scheduler(Linux IO 调度器)【转】

    每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...

  10. linux io的cfq代码理解

    内核版本: 3.10内核. CFQ,即Completely Fair Queueing绝对公平调度器,原理是基于时间片的角度去保证公平,其实如果一台设备既有单队列,又有多队列,既有快速的NVME,又有 ...

随机推荐

  1. 【[APIO/CTSC2007]动物园】状压DP

    题目测评:https://www.luogu.org/problemnew/show/P3622 题目描述 新建的圆形动物园是亚太地区的骄傲.圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围 ...

  2. JVM之类加载机制

    JVM之类加载机制 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 类加载五部分 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这 ...

  3. Windows NLB搭配IIS的ARR搭建高可用环境(转载)

    原文地址:http://www.cnblogs.com/shanyou/archive/2010/04/28/1723276.html 在现行的许多网络应用中,有时一台服务器往往不能满足客户端的要求, ...

  4. 【BZOJ1053】[HAOI2007]反素数 (搜索+数论)

    \([POI2002][HAOI2007]\)反素数 题目描述 对于任何正整数x,其约数的个数记作\(g(x)\).例如\(g(1)=1.g(6)=4\). 如果某个正整数x满足:\(g(x)> ...

  5. 【问题记录】element is not attached to the page document

    遇到ui脚本报错:element is not attached to the page document 解决办法,再次定位即可

  6. python语法学习面向对象之继承

    python语法学习面向对象之继承 转载自:http://www.cnblogs.com/Joans/archive/2012/11/09/2757368.html 只要涉及到面向对象,”类“是必须出 ...

  7. mysql5.6 的st_distance 实现按照距离远近排序。

    当前所处在的位置(113.858202 , 22.583819 ),需要查询我附近1000米内的小区,并安装由近到远的顺序排列  SELECT s.id,s.name,s.lng,s.lat, rou ...

  8. Spring学习笔记(五)—— Spring整合JDBC

    一.Spring对JDBC的支持 Spring提供了很多模板整合Dao技术 与JDBC的整合中,Spring中提供了一个可以操作数据库的对象——JdbcTemplate,该对象封装了JDBC技术,与D ...

  9. [微信小程序] -- wxss引用外部css文件及iconfont

    小程序引入外部文件的方式是: 只需要在其css文件写上: @import "外部css地址.wxss"; 因为项目需要, 小程序中需要使用iconfont , 很容易就想到了H5的 ...

  10. ssh,hibernate动态映射多表

    [From] http://www.07net01.com/2016/01/1172051.html 最近在做OA系统(ssh),一直在想如何把框架架得更完善,此前已经在框架里集成springMVC, ...