APUE-第十四章 高级I/O

1、非阻塞I/O

不会永远阻塞的I/O操作。

对于一个给定的文件描述符,有两种方法指定非阻塞I/O

①调用open指定O_NONBLOCK标志。

②对已经打开的描述符,调用fcntl,修改一打开文件描述符的O_NONBLOCK标志。

 

2、记录锁。

record locking

当第一个进程正在读或修改文件的某个部分时,使用记录锁可以阻止其他进程修改同一文件区。(字节范围锁)

apue.h

请求和释放一把锁

int               lock_reg(int,int, int, off_t, int, off_t);

 

#define       read_lock(fd,offset, whence, len) \

                            lock_reg((fd),F_SETLK, F_RDLCK, (offset), (whence), (len))

#define       readw_lock(fd,offset, whence, len) \

                            lock_reg((fd),F_SETLKW, F_RDLCK, (offset), (whence), (len))

#define       write_lock(fd,offset, whence, len) \

                            lock_reg((fd),F_SETLK, F_WRLCK, (offset), (whence), (len))

#define       writew_lock(fd,offset, whence, len) \

                            lock_reg((fd),F_SETLKW, F_WRLCK, (offset), (whence), (len))

#define       un_lock(fd,offset, whence, len) \

                            lock_reg((fd),F_SETLK, F_UNLCK, (offset), (whence), (len))

测试一把锁

pid_t lock_test(int,int, off_t, int,off_t);            

 

#define       is_read_lockable(fd,offset, whence, len) \

                            (lock_test((fd),F_RDLCK, (offset), (whence), (len)) == 0)

#define       is_write_lockable(fd,offset, whence, len) \

                            (lock_test((fd),F_WRLCK, (offset), (whence), (len)) == 0)

记录锁的自动继承和释放3条规则:

²  锁与进程和文件两者相关联

²  fork产生的子进程不继承父进程所设置的锁

²  在执行exec后,新程序可以继承原执行程序的锁

在文件尾端加锁

Writew_lock(fd,o,SEEK_END,O)

Write(fd,buf,1);

Unclock(fd,o,SEEK_END);

Write(fd,buf,1);

 

建议性锁:

强制性锁:让内核检查每一个openreadwrite,验证调用进程是否违背了正在访问的文件上的某一把锁。

 

一般的Unix系统文本编辑器并不使用记录锁。(该文件的最后结果取决于写该文件的最后一个进程)

 

3、死锁

1)条件:要有一个或多个线程、一个或多个资源,每个线程都在等待其中的一个资源,但所有的资源都已经被占用。所有线程都在互相等待,但他们永远不会释放已经占有的资源。

2)避免死锁的规则:

  • 按顺序加锁。
  • 防止发生饥饿
  • 不重复请求同一个锁
  • 设计应力求简单

 

4I/O多路转接

先构造一个我们所关心的描述符列表,然后调用函数(selectpselectpoll)直到这些描述符中的一个已经准备好进行I/O时,该函数才返回。

#include

Int select(int maxfdl,

fd_set *restrict readfds,

fd_set *restrict writefds,

fd_set *restrict exceptfds,

struct timeval *restricttvptr);

 

 

5、异步I/O

POSIX异步I/O接口使用AIO控制块来描述I/O操作。

Struct aiocb

{

}

 

6、函数readv  writev

用于在一次函数调用中读、写多个非连续缓冲区。---散布读、聚集写

#include

Ssize_t readv(int fd, const struct iovec*iov, int iovcnt);

Ssize_t writev(int fd, const struct iovec*iov, int iovcnt);

 

Struct iovec{

                   Void*iov_base;   //starting addressof buffer

                   Size_tiov_len;    //sizeof buffer

}

 

7、函数readn  written

读写指定的N字节数据,并处理返回值可能小于要求值的情况。

#include “apue.h”

Ssize_t readn(int fd, void *buf, size_tnbytes);

Ssize_t writen(int fd, void *buf,size_tnbytes);

 

8、存储映射I/O

Memory-mapped I/O

将一个磁盘文件映射到存储空间中的一个缓冲区上,当从缓冲区中取数据时,就相当于读文件中的相应字节。与此类似,将数据存入缓冲区时,相应字节就自动写入文件。

#include

告诉内核将一个给定文件映射到一个存储区域中,返回映射区的起始地址。

Void *mmap(void *addr, size_t len, intprot, int flag, int fd, off_t off);

更改现有映射的权限

Int mprotect(void *addr, size_t len, intprot);

将已经修改的页“冲洗”到被影射的文件中。

Int msync(void *addr, size_t len, intflags);

解除存储映射区的映射

Int munmap(void *addr, size_tlen);


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值