十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
管道(PIPE)
創(chuàng)新互聯(lián)專注于仲巴企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),購物商城網(wǎng)站建設(shè)。仲巴網(wǎng)站建設(shè)公司,為仲巴等地區(qū)提供建站服務(wù)。全流程定制開發(fā),專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
管道是一種最基本的IPC機制,由pipe函數(shù)在內(nèi)核中開辟一塊緩沖區(qū)(稱為管道)用于通信,所以管道在用戶程序看起來就像一個打開的文件,通過read(filedes[0]);或者write(filedes[1]);
int pipe(int filedes[2]);
參數(shù):filedes參數(shù)傳給用戶程序兩個文件描述符表。filedes[0]指向管道的讀端,filedes[1]指向管道的
寫端
返回值:成功返回0,失敗返回-1
int fseek(FILE *stream, long offset, int fromwhere);
stream:將指向以fromwhere為基準(zhǔn)
offset:偏移offset(指針偏移量)個字節(jié)的位置
返回值:
失?。?比如offset超過文件自身大小),則不改變stream指向的位置,函數(shù)返回一個非0值。
成功:stream將指向fromwhere,偏移量offset個字節(jié)的位置。
父子進程通信的步驟:
1.父進程創(chuàng)建管道,開辟管道,得到兩個文件描述符指向管道的兩端 | ![]() |
2.父進程fork創(chuàng)建出子進程,那么子進程也有兩個文件描述符指向同一管道 | ![]() |
3.父進程關(guān)閉fd[0],子進程關(guān)閉fd[1]。父進程可以往管道里寫,子進程可以往管道里讀,管道是環(huán)形隊列實現(xiàn)的,數(shù)據(jù)從寫端流入,讀端流出,這就實現(xiàn)了進程間通信。 | ![]() |
管道內(nèi)部的實現(xiàn)機制:
實際上管道沒有單獨的實現(xiàn)數(shù)據(jù)結(jié)構(gòu) ,他利用文件在Linux中,而是借助文件系統(tǒng)的file結(jié)構(gòu)和VFS文件索引節(jié)點inode,通過將兩個 file 結(jié)構(gòu)指向同一個臨時的VFS 索引節(jié)點,而這個 VFS 索引節(jié)點又指向一個物理頁面而實現(xiàn)的。有兩個file數(shù)據(jù)結(jié)構(gòu),但它們定義文件操作例程地址是不同的,其中一個是向管道中寫入數(shù)據(jù)的例程地址,而另一個是從管道中讀出數(shù)據(jù)的例程地址。這樣,用戶程序的系統(tǒng)調(diào)用仍然是通常的文件操作,而內(nèi)核卻利用這種抽象機制實現(xiàn)了管道這一特殊操作。
測試管道容量
測試原理:讀端不讀,寫端一直寫
#include#include #include #include #include #include int get_pipe_size(FILE* fd) { fseek(fd,0,SEEK_SET); int start = ftell(fd); fseek(fd,0,SEEK_END); int end = ftell(fd); return end - start; } int main() { int _pipe[2]; int ret = pipe(_pipe); if(ret == -1) { // printf("create pipe error ,error code is:%d\n",error); return 1; } pid_t id = fork(); if(id <0) { printf("fork error"); return 2; } else if(id == 0) //child 關(guān)閉讀端 { close(_pipe[0]); int i =0; char* _msg = NULL; //the writer keep writing while(1) { _msg = "r"; write(_pipe[1],_msg,strlen(_msg)); //一直寫 printf("%d\n",i); i++; } printf("write over...\n"); } else { //father close(_pipe[1]);//關(guān)閉寫端 char _msg[100]; int j =0; sleep(5); int status = 0; while(1) { status = 0; memset(_msg,'\0',sizeof(_msg)); printf("%s:code id:%d\n",_msg,ret); } if(waitpid(id,&status,0)<0) { return 3; } printf("status:%d\n",(status)&0xff); } return 0; }
測試結(jié)果:大約64k