日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Linux的高效的數(shù)據(jù)傳輸技術(shù)-Relay( 二 )


面向用戶空間的 API
這些 Relay 編程接口向用戶空間程序提供了訪問(wèn) relay 通道緩沖區(qū)數(shù)據(jù)的基本操作的入口,包括:
●open() - 允許用戶打開一個(gè)已經(jīng)存在的通道緩沖區(qū) 。
●mmap() - 使通道緩沖區(qū)被映射到位于用戶空間的調(diào)用者的地址空間 。要特別注意的是,我們不能僅對(duì)局部區(qū)域進(jìn)行映射 。也就是說(shuō),必須映射整個(gè)緩沖區(qū)文件,其大小是 CPU的個(gè)數(shù)和單個(gè) CPU 緩沖區(qū)大小的乘積 。
●read() - 讀取通道緩沖區(qū)的內(nèi)容 。這些數(shù)據(jù)一旦被讀出,就意味著他們被用戶空間的程序消費(fèi)掉了,也就不能被之后的讀操作看到 。
●sendfile() - 將數(shù)據(jù)從通道緩沖區(qū)傳輸?shù)揭粋€(gè)輸出文件描述符 。其中可能的填充字符會(huì)被自動(dòng)去掉,不會(huì)被用戶看到 。
●poll() - 支持 POLLIN/POLLRDNORM/POLLERR 信號(hào) 。每次子緩沖區(qū)的邊界被越過(guò)時(shí),等待著的用戶空間程序會(huì)得到通知 。
●close() - 將通道緩沖區(qū)的引用數(shù)減1 。當(dāng)引用數(shù)減為0時(shí),表明沒(méi)有進(jìn)程或者內(nèi)核用戶需要打開它,從而這個(gè)通道緩沖區(qū)被釋放 。
面向內(nèi)核空間的 API
這些API接口向位于內(nèi)核空間的用戶提供了管理relay通道、數(shù)據(jù)寫入等功能 。下面介紹其中主要的部分,完整的API接口列表請(qǐng)參見(jiàn)這里 。
●relay_open() - 創(chuàng)建一個(gè)relay通道,包括創(chuàng)建每個(gè)CPU對(duì)應(yīng)的relay緩沖區(qū) 。
●relay_close() - 關(guān)閉一個(gè)relay通道,包括釋放所有的relay緩沖區(qū),在此之前會(huì)調(diào)用relay_switch()來(lái)處理這些relay緩沖區(qū)以保證已讀取但是未滿的數(shù)據(jù)不會(huì)丟失
●relay_write() - 將數(shù)據(jù)寫入到當(dāng)前CPU對(duì)應(yīng)的relay緩沖區(qū)內(nèi) 。由于它使用了local_irqsave()保護(hù),因此也可以在中斷上下文中使用 。
●relay_reserve() - 在relay通道中保留一塊連續(xù)的區(qū)域來(lái)留給未來(lái)的寫入操作 。這通常用于那些希望直接寫入到relay緩沖區(qū)的用戶 ??紤]到性能或者其它因素,這些用戶不希望先把數(shù)據(jù)寫到一個(gè)臨時(shí)緩沖區(qū)中,然后再通過(guò)relay_write()進(jìn)行寫入 。
Relay的例子
我們用一個(gè)最簡(jiǎn)單的例子來(lái)介紹怎么使用Relay 。這個(gè)例子由兩部分組成:一部分是位于內(nèi)核空間將數(shù)據(jù)寫入relay文件的程序,使用時(shí)需要作為一個(gè)內(nèi)核模塊被加載;另一部分是位于用戶空間從relay文件中讀取數(shù)據(jù)的程序,使用時(shí)作為普通用戶態(tài)程序運(yùn)行 。
內(nèi)核空間的程序主要操作是:
加載模塊時(shí),打開一個(gè)relay通道,并且往打開的relay通道中寫入消息;
卸載模塊時(shí),關(guān)閉relay通道 。
程序內(nèi)容:

/*
* hello-mod.c
* a kernel-space client example of relayfs filesystem
*/
#include
#include
static struct rchan *hello_rchan;
int init_module(void)
{
const char *msg="Hello worldn";
hello_rchan = relay_open("cpu", NULL, 8192, 2, NULL);
if(!hello_rchan){
printk("relay_open() failed.n");
return -ENOMEM;
}
relay_write(hello_rchan, msg, strlen(msg));
return 0;
}
void cleanup_module(void)
{
if(hello_rchan) {
relay_close(hello_rchan);
hello_rchan = NULL;
}
return;
}
MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION ("Simple example of Relay");
用戶空間的函數(shù)主要操作是:
●如果relayfs文件系統(tǒng)還沒(méi)有被mount,則將其mount到目錄/mnt/relay上;
●遍歷每一個(gè)CPU對(duì)應(yīng)的緩沖文件;
●打開文件;
●讀取所有文件內(nèi)容;
●關(guān)閉文件;
●最后,umount掉relay文件系統(tǒng) 。
程序內(nèi)容:

/*
* audience.c
* a user-space client example of relayfs filesystem
*/
#include
#include
#include
#include
#include
#include
#include
#define MAX_BUFLEN 256
const char filename_base[]="/mnt/relay/cpu";

推薦閱讀