UNIX环境高级编程 - 文件I/O - 原子操作、复制、修改文件描述符

原子操作

  1. 追加到一个文件
  • 追加一个文件时,不能通过lseek到末尾然后write。要用O_APPEND选项打开文件,然后直接write
    • 通过lseek到末尾然后write时,如果多个进程同时执行这两个操作,则会引起竞争条件
    • 通过 O_APPEND选项打开文件,然后直接write时,内核每一次在写操作之前,都会将进程的当前偏移量设置到文件的末尾,于是就不需要执行lseek定位操作
  • pread/pwrite可以执行原子性的定位读/定位写
  • O_CREAT|O_EXCL选项打开文件时,可以原子性的检查文件是否存在和创建文件这两个操作。
  1. 函数 preadpwrite
#include <unistd.h>
ssize_t pread(int fd,void*buf,size_t nbytes,off_t offset);
ssize_t pwrite(int fd,const void*buf,size_t nbytes,off_t offset);
  • 参数:
    • fd:打开的文件描述符
    • buf:读出数据存放的缓冲区/ 写到文件的数据的缓冲区
    • nbytes:预期读出/写入文件的字节数
    • offset:从文件指定偏移量开始执行read/write
  • 返回:
    • 成功:读到的字节数/已写的字节数
    • 失败: -1

调用pread相当于先调用lseek再调用read.但是调用pread时,无法中断其定位和读操作,并且不更新当前文件偏移量;调用pwrite相当于先调用lseek再调用write.但是调用pwrite时,无法中断其定位和写操作,并且不更新当前文件偏移量

其他操作

dup

使用dup/dup2复制一个现有的文件描述符:

#include <unistd.h>

int dup(int fd);
int dup2(int fd,int fd2);
  • 参数:
    • fd:被复制的文件描述符(已被打开)
    • fd2:指定的新的文件描述符(待生成)
  • 返回值:
    • 成功: 返回新的文件描述符
    • 失败: 返回 -1

对于dup函数,返回的新的文件描述符一定是当前可用的文件描述符中最小的数字。

对于dup2函数:

  • 如果 fd2已经是被打开的文件描述符且不等于fd,则先将其关闭,然后再打开(原子操作)
  • 如果 fd2等于fd,则直接返回fd2(也等于fd),而不作任何操作

任何情况下,这个返回的新的文明描述符与参数fd共享同一个文件表项(因此文件状态标志以及文件偏移量都会共享)。任何情况下,这个返回的新的文明描述符的close-on-exec标志总是被清除。

dup后的内核数据结构如下:

E

sync

UNIX操作系统在内核中设有缓冲区,大多数磁盘 I/O 都通过缓冲区进行。当用户程序想文件写入数据时,内核通常都首先将数据复制到缓冲区中,然后排入队列,晚些时候再写入磁盘。这种方式称为延迟写。

  • 当内核需要重用缓冲区来存方其他数据时,它会把所有延迟写的数据库写入磁盘
  • 也可以调用下列函数来显式的将延迟写的数据库写入磁盘
#include <unistd.h>

int fsync(int fd);
int fdatasync(int fd);
void sync(void);
  • 参数:

    • fd:指定的打开的文件描述符
  • 返回值:

    • 成功:返回 0
    • 失败: 返回 -1

区别:

  • sync:将所有修改过的块缓冲区排入写队列,然后返回,它并不等待时机写磁盘结束
  • fsync:只对由fd指定的单个文件起作用,等待写磁盘操作结束才返回
  • fdatasync:只对由fd指定的单个文件起作用,等待写磁盘操作结束才返回,但是它只影响文件的数据部分(fsync会同步更新文件的属性)

update 守护进程会周期性的调用sync函数。命令sync也会调用sync函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值