對一些低速的系統調用可能會是得,進程阻塞
讀不到 數據還沒來, 管道、網絡設備、終端設備
寫滿了 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]的數據輸出到文件
依次行讀寫,可免去多次系統調用!高效!