Linux_UNIX编程手册-读书笔记-第五章(深入探究文件I/O)

原子操作:将一次系统调用所需要的各个动作作为不可中断的操作,一次性加以执行。
原子操作是许多系统调用得以正确执行的必要条件。

5.1 原子操作与竞争条件

竞争状态:操作共享资源的两个进程(或线程),其结果取决于一个无法预期的顺序,这些进程(或线程)获得CPU使用权的先后相对顺序。

个人感觉就是线程安全之类的东西。

试图以独占方式打开文件的错误代码:
在这里插入图片描述

当两个进程在一个多CPU系统上同时运行时,可能出现以下情况:
在这里插入图片描述
看了半天没看懂他具体想表达什么,大概就是两个进程同时执行,都以为自己以独占的方式创建了文件。于是违背了原子操作原则。

append时,加入O_APPEND标志可以将文件偏移量的移动和数据写操作纳入同一原子操作。

5.2 文件控制操作 fcntl()

fcntl()系统调用对一个打开的文件描述符执行一系列控制操作。
在这里插入图片描述
fcntl函数的用途之一是针对一个打开的文件,获取或修改其访问模式和状态标志。
先通过设置cmd参数为F_GETFL获取设置,再通过F_SETFL进行设置。

访问模式的判定比较复杂,需要使用掩码O_ACCMODE与flag相与,再将结果与三个常量比对:

accessMode = flags & O_ACCMODE;	\\flags通过F_GETFL得到
if (accessMode == O_WRONLY || accessMode == O_RDWR)
	printf("file is writeable\n")

访问模式应该是不能设置的吧==

通过F_SETFL设置状态标志
允许修改的标志有:O_APPEND, O_NONBLOCK, O_NOATIME, O_ASYNC, O_DIREST.
使用fcntl修改文件状态标志,尤其适用于如下场景:
在这里插入图片描述
目前只在socket编程时用过fcntl=-=

5.4 文件描述符和打开文件之间的关系

文件描述符和文件之间的关系可以是多对一的,多个文件描述符指向同一打开文件,这些文件描述符可在相同或不同的进程中打开。

内核维护了三种数据结构:

  • 进程级的文件描述符
  • 系统级的打开文件表
  • 文件系统的i-node表

要点

  • 两个不同的文件描述符,若指向同一打开的文件句柄,将共享同一文件偏移量。

  • 文件描述符标志,为进程和文件描述符所私有,对标志的修改不会影响到其他文件描述符。

5.5 复制文件描述符

在这里插入图片描述
复制一个打开的文件描述符,返回一个新描述符,二者都指向同一打开的文件句柄

当复制需要调用者指定新文件描述符时,使用dup2:
在这里插入图片描述

fcntl()也可以复制文件描述符,且更加灵活:

cpp newfd = fcntl(oldfd, F_DUPFD, startfd);

dup3只增加了一个功能,即可以设置标志O_CLOEXEC.
在这里插入图片描述

5.6 特定偏移量处的I/O

在这里插入图片描述
pread和pwrite系统调用可以避免进程之间出现进程状态。

5.7分散输入和集中输出

一个文件描述符对应多个缓冲区
在这里插入图片描述

struct iovec{
	void *iov_base;		//缓冲区的起始地址
	size_t iov_len;		//缓冲区中数据的大小
};

分散输入:
原子性是readv()的重要特征。
readv将数据散置于iov指定的缓冲区中。(依次填满,从iov[0]开始)

集中输出
writev同样具有原子性
将iov中数据按顺序拼接起来,连续写入fd对应的文件中。

带偏移量的分散输入和集中输出
在这里插入图片描述

5.8 截断文件

在这里插入图片描述
将文件长度调整为length(通过截断或者在尾部添加空字节)

5.9 非阻塞I/O

设置O_NONBLOCK标志
内核缓冲区保证了普通文件I/O不会陷入阻塞,故打开普通文件时一般忽略O_NONBLOCK标志。
后面应该会对这个有比较详细的讲解

5.10 大文件I/O 略

5.11 /dev/fd 目录

对于每个进程,内核都提供有一个特殊的虚拟目录/dev/fd,目录中包含了进程中打开的文件描述符。
fd = open("/dev/fd/1", O_WRONLY); 对应标准输出。

5.12 创建临时文件

GUN C提供了一系列库函数用于创建临时文件,仅在程序运行期间使用,在这里插入图片描述
template最后6个字符必须为XXXXXX,这6个字符将被替换,修改后的字符串会被返回。
文件拥有者对打开的文件拥有读写权限。

在这里插入图片描述
tmpfile返回一个文件流,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值