眾所周知,TLS是指線程局部存儲,F(xiàn)IFO是Unix中的命名管道,可用于無關(guān)進(jìn)程間的通信,而本文描述的TLS FIFO是指這樣一種機(jī)制:如果一個線程在每次IO操作時,若沒有連接,則先連接到FIFO服務(wù)端,再將連接關(guān)聯(lián)到這個線程的TLS中,這里的連接即創(chuàng)建并打開唯一的FIFO,之后的讀寫就在這個FIFO連接上進(jìn)行;當(dāng)FIFO連接斷開時,在下次IO操作時會自動重連。這樣一來,用戶程序就只要調(diào)用相關(guān)的IO操作,而不必管理連接,極大地簡化了程序。使用FIFO通信前先要創(chuàng)建FIFO再打開它,其中創(chuàng)建是最重要的操作,結(jié)果有3種情況:成功、失敗和已存在。
結(jié)構(gòu)定義
typedef struct
{
int fd;
char *name;
}ipc_fifo_t;
fd存儲FIFO文件描述符,name存儲FIFO文件系統(tǒng)路徑名。
接口函數(shù)
● 創(chuàng)建FIFO
ipc_fifo_t* ipc_fifo_make(const char *path,mode_t mode);
path指定FIFO路徑,可以是絕對路徑或相對路徑,mode指定訪問權(quán)限,若成功則返回一個FIFO結(jié)構(gòu),否則為NULL;通常被ipc_fifo_open調(diào)用。
● 打開FIFO
int ipc_fifo_open(ipc_fifo_t **f,const char *path,int flag,mode_t mode);
flag指定打開標(biāo)志,如果包含了O_CREAT標(biāo)志,那么調(diào)用ipc_fifo_make創(chuàng)建新的FIFO對象并在打開成功后替換*f,否則如果*f為空,就分配并初始化一個fifo結(jié)構(gòu);mode指定訪問權(quán)限,僅當(dāng)創(chuàng)建時生效。雖然f為輸入輸出參數(shù),但操作失敗時不會影響它,也就是說沒有副作用。
● 發(fā)送數(shù)據(jù)
ssize_t ipc_fifo_write(ipc_fifo_t *f,const void *data,size_t size);
如果成功則返回已發(fā)送的字節(jié)數(shù),否則返回-1,errno表示出錯代碼。
● 接收數(shù)據(jù)
ssize_t ipc_fifo_read(ipc_fifo_t *f,void *data,size_t size);
如果成功則返回已發(fā)送的字節(jié)數(shù),否則返回-1,errno表示出錯代碼。
● 關(guān)閉FIFO
void ipc_fifo_close(ipc_fifo_t *f);
當(dāng)通信結(jié)束的時候,應(yīng)該調(diào)用此函數(shù)來關(guān)閉FIFO,它會先刪除FIFO文件和關(guān)閉文件描述符,最后釋放fifo結(jié)構(gòu)。
● 獲取TLS FIFO
ipc_fifo_t* ipc_fifo_tls_get();
該函數(shù)一般被發(fā)送數(shù)據(jù)接口調(diào)用,若成功則返回一個FIFO結(jié)構(gòu),否則為NULL;每個線程對應(yīng)一個FIFO對象,對于同一線程,獲取的是同一個FIFO對象,而后便可調(diào)用ipc_fifo_write來發(fā)送數(shù)據(jù)。
工作流程
適用于FIFO客戶端和服務(wù)端,但服務(wù)端由于要異步處理眾多FIFO客戶端,因此要注意以下2個問題,這也是使用FIFO技術(shù)通信的一些細(xì)節(jié)。
1)必須以非阻塞讀寫方式打開知名FIFO,即以O(shè)_CREAT|O_RDWR|O_NONBLOCK標(biāo)志來調(diào)用ipc_fifo_open,這樣才不會阻塞等待某個客戶端以同步寫方式打開知名FIFO而返回,因為它使用O_RDWR標(biāo)志,這樣自己既讀又寫,加上O_NONBLOCK,就立即返回了。
2)必須以非阻塞只讀方式打開對應(yīng)客戶端FIFO,即以O(shè)_RDONLY|O_NONBLOCK標(biāo)志調(diào)用ipc_fifo_open,這樣就不會阻塞接受客戶端建立連接而返回。
建立FIFO連接
適用于FIFO客戶端,被發(fā)送數(shù)據(jù)接口調(diào)用,考慮到服務(wù)端可能事先沒有打開知名FIFO來監(jiān)聽連接,所以這里先以
異步方式寫打開知名FIFO,如果成功則改以
阻塞方式發(fā)送唯一路徑名到服務(wù)端,如果發(fā)送完全后,接著以
同步方式寫打開唯一FIFO,這是為了等待服務(wù)端打開了對應(yīng)的唯一FIFO。
發(fā)送數(shù)據(jù)
適用于FIFO客戶端,當(dāng)TLS中沒有關(guān)聯(lián)對應(yīng)的FIFO時,則先調(diào)用fifo_tls_get進(jìn)入建立FIFO連接流程,而后再發(fā)數(shù)據(jù)。
posted on 2014-12-01 00:13
春秋十二月 閱讀(1349)
評論(2) 編輯 收藏 引用 所屬分類:
System