linux系統中的IO操作

2021-07-23 22:43:49 字數 4245 閱讀 4497

同步io分為阻塞io、非阻塞io、訊號驅動的io和多路轉接io。

阻塞io:

一直阻塞程序直到完成io操作。

非阻塞io:

有資料時進行io操作,沒有資料時立即返回不阻塞程序。

訊號驅動io:

當有資料到來是傳送訊號給程序執行io操作,提高cpu的利用率。當設定開啟檔案描述字o_async標誌是可以用於訊號驅動的io操作,也可以用過fcntl()改變檔案標籤,當檔案進行io操作時會產生sigio訊號或套接字有帶外資料到來時會產生sigurg訊號。通過fcntl函式執行f_setown命令可以設定/獲得,接收訊號的程序/程序組id。

具體例項:

/*

* main.c

* * created on: 2023年10月22日

* author: chy

*/#include #include #include #include #include #include #include #include #include file *file;

void sigfunc(int sig)

} }}int main(int argc,char *argv)

多路轉接io:

處理來自多個通道的輸入,通過select函式告訴呼叫它的程序需要等待io事件的數量。

#include #include int select(int nfds,fd_set *rfds,fd_set *wfds,fd_set *edfs,struct timeval *timeout);

void fd_zero(fd_set *fdset); //初始化描述字為空

void fd_clr(int filedes,fd_set *fdset); //將filedes描述字從fdset描述字集合中清除

int fd_isset(int fileds,fd_set *fdset); //判斷filedes是否屬於fdset所指的描述

void fd_set(int filedes,fd_set *fdset); //將filedes新增到描述字fset所指的集合中

select中的三個測試描述字集合都為空可以做為定時器切精度高於sleep。

非同步io

:能夠在較短時間內從多個接收通道收集大量的資料,非同步io操作在io期間不阻塞發出io請求的程序,其io操作由作業系統派生新的執行緒並行的執行,當io操作結束是傳送訊號給傳送請求io操作的程序通知其io操作完成,程序也可以呼叫aio_suspend阻塞程序等待io操作完成。

#include int aio_write(struct aiocb *aiocbp);//返回實際寫入的位元組數

int aio_read(struct aiocb *aiocbp); //返回實際讀出的位元組數

int lio_listio(int mode,struct aiocb *restrict const list[restrict],int nent,struct sigevent *restrict notification);

int aio_error(struct aiocb *aiocbp); //正在進行io操作返回einprogress

ssize_t aio_return(struct aiocb *aiocbp); //返回讀寫位元組個數

int aio_suspend(const struct aiocb *const list,int nent,const struct timespec *timeout); //掛起呼叫程序直到io完成或時間到期

int aio_sysnc(int op,struct aiocb *aiocbp); //把資料同步到物理磁碟

struct aiocb;

struct sigevent;

具體例項:

/*

* main.c

* * created on: 2023年10月20日

* author: chy

*/#include #include #include #include #include #include #include #include #include #include #define buffer_num 2

#define buffer_size 2048

#define err(msg,f_num) \

}typedef enumbuffer;

typedef struct buffer_t;

static buffer_t buffer[buffer_num];

static sigset_t procmask;

static int write_num = 0;

static int sig_num;

static volatile off_t seek_ptr;

void sig_func(int signo,siginfo_t *info,void *sig)

buffer_t *find_empty_buffer()

buffer[i].state = buffer_full;

buffer[i].fillpt = 0;

sigprocmask(sig_setmask,&procmask,null); //恢復遮蔽非同步寫訊號量

return (&buffer[i]);

}void buffer_flush(buffer_t *temp)

int main(int argc,char *argv)

file_in = open(argv[1],o_rdonly);

err("open file_in faile\n",file_in);

file_out = open(argv[2],o_wronly | o_creat,0777);

err("open file_out faile\n",file_out);

for(i = 0; i < buffer_num; i++)

buffer_opt = find_empty_buffer();

sigemptyset(&procmask);

sigaddset(&procmask,sigrtmin);

sigemptyset(&sig.sa_mask);

sig.sa_flags = sa_siginfo;

sig.sa_sigaction = sig_func;

err("sigaction fail\n",sigaction(sigrtmin,&sig,null));

int read_num;

while(1)

}if(errno == eintr)

break;

else if(read_num < 0 && errno != eintr)

err("read faile\n",-1);

} if(read_num == 0)

} for(i = 0; i < buffer_num; i++)

if(buffer[i].state == buffer_write)

close(file_out);

close(file_in);

printf("this is over\n");

return 1;

}

儲存對映io:傳統io進行讀寫檔案要進行多次系統呼叫,並且把檔案載入到自己的位址空間,其效率低,浪費儲存空間。儲存對映io,系統把檔案的一頁讀取到記憶體,每乙個程序把改頁對映到自己的記憶體空間。對映後不再需要read等系統呼叫,可以通過指令直接訪問。儲存對映分為共享對映和私有對映,共享對映每個程序都能夠改變對映頁的內容,當一頁被重新整理時保回會物理磁碟。私有對映,寫檔案將導致複製該頁的乙個副本,物理磁碟物件本身不改變。

#include void *mmap(void *addr,size_t len,int port,int flags,int filedes,off_t off);

int munmap(void *paddr,size_t len); //刪除對映

int msync(void *addr,size_t len,int flags); //寫入到物理磁碟

addr:對映區在記憶體的起始位址。

len:對映的位元組數。

prot:對映區的保護許可權。

flags:對映區的屬性。

filedes: 已開啟檔案的描述字。

off:檔案要對映的其實位元組位置。

linux系統IO操作

clib buff page cache disk cache include 開啟流 file fopen const char pathname,const char type 關閉流 int fclose file fp 重新整理流 int fflush file fp 一次讀寫乙個字元 in...

Linux系統中的I O模型

1.linux系統中i o模型 io模型有四種 1 同步阻塞i o模型 2 同步非阻塞i o模型 3 非同步阻塞i o模型 4 非同步非阻塞i o模型 備註,像select poll以及epoll屬於是非同步阻塞io的類別。阻塞與非阻塞是正對程序自身而言的,就是程序在進行io操作的時候,可不可以處理...

Linux系統IO目錄檔案操作

linux目錄檔案 維護著乙個鍊錶的資料結構,目錄檔案的結構和單向鍊錶的節點的類似,可利用鍊錶的遍歷方法來實現目錄檔案遍歷.但是直接使用目錄流物件不會得到乙個鍊錶的節點 因為是流物件 需要配合readdir指令來移動流的當前位置指標,並獲得相應的鍊錶節點 目錄下的檔案的資訊 include incl...