函式解析:此系統呼叫用於建立乙個同步io環境,可以同時處理maxevents個操作,ctxp必須初始化為0,io_setup會自動分配填充空間,所以,呼叫後一定要掉用io_destroy進行釋放掉。io_setup函式:
返回值:
成功為0,失敗為以下值
eagain:maxevents已經超過個系統使用者的限制,即檔案/proc/sys/fs/aio-max-nr中的數字
efault:分配給ctxp的指標無效
einval:ctxp未初始化為0或者maxevents超限。
enomem:核心資源不足。(說明系統壓力大)
enosys:未實現此系統呼叫
io_destroy函式:
釋放io_setup建立的非同步io環境,系統呼叫將嘗試取消針對ctx_id的所有未完成的非同步i/o操作,阻塞在不能不取消的操作上直到操作完成。
返回值:
成功為0,失敗為以下值
efault:分配給ctxp的指標無效
einval:分配給ctxp的指標無效
enosys:未實現此系統呼叫
io_submit函式:提交事件
將ios設定的事件,提交到ctx佇列中,等待事件排隊處理。
返回值:
成功:0~nr
eagain:系統內資源不夠用。
ebadf:提交的檔案描述符不對,可能是不支援非同步操作的檔案描述符或者無用已關閉的檔案描述符。
efault:某一部分指標無效
einval:引數有問題,檢查引數設定。
io_cancel函式:
io_cancel()系統呼叫試圖取消以前用io_submit(2)提交的非同步i/o操作。iocb引數描述要取消的操作,ctx引數是提交操作的非同步環境上下文。如果操作被成功取消,則事件將被複製到由結果指向的記憶體中,而不會被放到完成佇列中。
返回值:
成功0,失敗如上
io_getevents函式:
io_getevents系統呼叫讀取ctx非同步環境中至少min_nr至多nr個事件,(前提是timeout為null阻塞到至少符合條件數目的事件,如果設定超時,則在一定的時間後返回)
返回值:成功則為完成的事件,0則表示沒有完成的事件。失敗如上。
**示例(用來測試非同步io落盤速度)
#include #include#include
#include
/*for syscall()
*/#include
/*for __nr_* definitions
*/#include
/*for aio types and constants
*/#include
/*o_rdwr
*/#include
/*memset()
*/#include
#include
#include
#define count_pthread 8
#define value_size 4*1024*1024ul
#define count_value 256
#define count_loop 10
static uint8_t * value =null;
inline
int io_setup(unsigned nr, aio_context_t *ctxp)
inline
intio_destroy(aio_context_t ctx)
inline
int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
inline
int io_getevents(aio_context_t ctx, long min_nr, long max_nr, struct io_event *events, struct timespec *timeout)
static uint32_t get_now_time(char *data ,uint32_t channle_id)
; gettimeofday(&tv, null);
strftime(time,
60,"
%y-%m-%d-%h-%m-%s
",localtime(&tv.tv_sec));
sprintf(data,
"/data/brickmd0p1/ch%d-%s-%3d-%d.dat
",channle_id,time ,(int)(tv.tv_usec / 1000),cnt++);
printf(
"get_now_time\n");
return0;
}int * openfile(void);
intfd[count_pthread];
fd = (int *)malloc(sizeof(int) *count_pthread);
if(fd ==null)
return
null;
for(i = 0; i < count_pthread;i++)
}return
fd;
}void * write_file(void *s)
ctx = 0
; ret = io_setup(256, &ctx);
if (ret < 0
)
/*setup i/o control block
*/memset(&cb, 0, sizeof
(cb));
cb.aio_fildes = *(int*)s;
cb.aio_lio_opcode = iocb_cmd_pwrite;/*
command-specific options
*/cb.aio_buf =(uint64_t)value;
cb.aio_offset = 0
; cb.aio_nbytes =value_size;
cbs[
0] = &cb;
for(i = 0; i < count_value;i++)
cb.aio_offset +=value_size;
}ret =io_destroy(ctx);
if (ret < 0
)
}int main(void
) value =value1;
memset(value,
0,value_size);
for(i=0;i)
gettimeofday(&start_t,null);
for(i = 0; i < count_pthread; i++)
for(i = 0; i < count_pthread; i++)
gettimeofday(&end_t,null);
if(end_t.tv_usec >=start_t.tv_usec)
total_t = (double)(end_t.tv_sec - start_t.tv_sec)+(double)(end_t.tv_usec-start_t.tv_usec)/1000000.0
;
else
total_t = (double)(end_t.tv_sec - start_t.tv_sec-1)+(double)(end_t.tv_usec+1000000.0-start_t.tv_usec)/1000000.0
; printf(
"recv 0 ch:--------speed:---%lf mb/s---------\n"\
, (double) value_size * count_pthread * count_value/ total_t/1024/1024
);
for(i = 0; i < count_pthread; i++)
free
(value1);
}
非同步I O之檔案
一 概念 1.1 開啟裝置的操作會向作業系統傳送請求,createfile函式會直接返回,而不會去等待操作完成。1.2 此時作業系統會發現這個請求,然後作業系統會來進行實際的操作,當操作完成之後,1.3 會設定一些標誌,也就是通知。1.4 在作業系統進行實際操作的時候,我可以來做一些想要做的操作,當...
非同步IO的應用
迴圈 早期系統使用簡單的迴圈選擇解決方案,即迴圈遍歷開啟的網路連線的列表,判斷是否有要讀取的資料。這種方法既緩慢 尤其是隨著連線數量增加越來越慢 又低效 因為在處理當前連線時其他連線可能正在傳送請求並等待響應 在系統迴圈遍歷每個連線時,其他連線不得不等待。如果有 100 個連線,其中只有乙個有資料,...
非同步 佇列寫日誌檔案
using system using system.collections.generic using system.io using system.linq using system.text using system.threading.tasks namespace sysloginfo 寫入...