高级I/O

来源:互联网 发布:贪吃蛇java代码详解 编辑:程序博客网 时间:2024/05/19 13:26


对一些低速的系统调用可能会是得,进程阻塞

读不到     数据还没来, 管道、网络设备、终端设备

写满了     FIFO

打开不了,终端要先等待调制解调器应答。。。

ioctl

进程通信

磁盘读写是会暂时阻塞调用者,但磁盘I/O系统调用不是“低速”的



非阻塞I/O,使得open read write 方式i/o时,这些操作不会永远阻塞!

对一个给定的问价描述符,可用O_NONBLOCK, fcntl 设置O_NONBLOCK设置非阻塞I/O

对非阻塞I/O,操作失败时返回错误结果,一般采用轮询方式,在多用户系统上轮询消耗cpu资源!


记录锁


linux中使用关闭组执行位,待开组设置未,来表示开启强制性记录锁,这种位设置是没意义的,因此可以待边开启强制性记录锁!仅仅有表示开启强制性记录锁的作用!


I/O多路转接



#iclude <sys/select.h>

int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct  timeval *tvptr);

超时返回0

有监控的文件准备好,返回准备好的fd数

错误返回-1


maxfds表示最大的描述符+1,描述符从0开始,实际上他是记录要检查的描述符数,set中对应标号中fd存在则表示在集合中,只需要扫描到maxfd就能保证所有的fds都扫描到了

set分别表示监控的 读 , 写,异常的fd集合

返回通过 readset writeset exceptset指针返回,表示准备好的集合

准备好的含义:

读:读相应描述符时不会阻塞

写:写时不会阻塞

异常L描述符中有未决条件


FD_ISSET    判断是否在集合中

FD_CLR       集合中删除

FD_SET        添加到集合

FD_ZERO    清空集合


select 在需要循环检测fd,而且最多只能优1024个文件,对于访问量小的任务,可以采用此模型

而且相对于多线程,资源消耗少,编码简单


pselect 功能select类似,添加了屏蔽字!

时间是timespec



函数poll

#include <poll.h>

int poll(struct pdllfd fdarry[], nfds_fds, int timeout);

fdarry 要监控的文件符数组,要删除某一个fd 值设为0;

nfds_fds 数量,可以超过1024

timeout  -1 永远等待

                 0 立即返回

                >0 指定毫秒数


struct pollfd

{

    int fd;

    short events;//监控的读写等事件

    short revent;//返回的准备好的事件

}

events

POLLIN                        等价于POLLNORMAL | POLLRDBAND

POLLRDNORMAL    无阻塞读普通数据

POLLRDBAND           无阻塞读优先数据(待查!)

POLLOUT                    普通无阻塞写

POLLEWRNORMAL  普通无阻塞写

POLLERR  已经出

POLLHUP  已挂断   解调器已经挂断 不同于文件尾(尾可读返回0EOF)

POLLNVAL 描述符未打开



select & poll不是自动重启的,可能会被中断,中断返回-1

ppoll可设置屏蔽中断字


posix异步I/O 

struct aiocb

{

   int aio_filded;//文件fd

   int aio_offset;//io的偏移起始地址

   volatile void * aoi_buf;//缓存地址

    int aio_nbytess;//io字节数

    int aio_reqprio;//优先级,有限的顺序排队参考

    struct sigevent aio_sigevnet;//io完毕时如何通知程序,可能产生指定的信号,由用户决定产生什么信号

    int aio_lio_opcode;//只对函数lio_listio有效,指定读操作,写 还是被忽略的空操作,读会以list中的aio为参数调用aio_read,写aio_write

;}


#include <aio.h>

int aio_read(struct aiocb *cb);

int aio_read(struct aiocb *cb);

int aio_fsync(int op,struct aiocb *cb);

sync只同步数据信息 ,O_SYNC同fsync同时同步文件信息

int aio_error(const struct aiocb *cb);

返回当前io的状态

0成功

-1 调用失败,设在errno

EINPROGRESS 正在读写或者等待

成功可调用aio_return


size_t aio_return(const struct aiocb *cb);

获取io结束后的返回值

调用一次清除保存的返回值信息

在io未结束之前,调用结果是未定义的


int aio_suspend(const struct aiocb *const list[], int nent, const struct timespec *timeout);

可能其他操作在io之前完成

等待指定aiocb列表中的任意一个完成io

任意一个完成io 返回0

超时返回-1

被中断,返回-1 ,errno=EINTR

int aio_cancel(int fd, struct aiocb *cb);

cb == NULL ,取消所有fd上的io

不一定能取消成功

AIO_DONE io已经在取消前完成

AIO_CANCELED  全部被取消

AIO_NOTCANCELED  至少有一个没取消

-1  调用失败


readv writev

#include <uio.h>

ssize_t readv(int fd, const struct iovec *iov, int iocnt);

ssize_t writev(int fd, const struct iovec *iov, int iocnt);

struct iovec

{

    void *iov_base;//缓存的起始地址

    size_t iov_len;//缓存的长度

}

iocnt代表数组中iovec的个数

一次性从文件中读数据,依次填充到iov[0],iov[1],iov[2]直到iov[iocnt - 1]的数据被填满,或者文件尾!

一次性从iov[0----iocnt - 2]的数据输出到文件

依次行读写,可免去多次系统调用!高效!














0 0
原创粉丝点击